【发布时间】:2022-01-01 09:02:53
【问题描述】:
我有一个代码可以从数据库中获取所有商品价格,然后调用 API 来更新它们。
由于某种原因,我的 Button1_click 函数内的循环不起作用,但在 Button2_click 上没有循环的类似代码可以正常工作。我不明白为什么。
我可以在输出中看到 API 调用的结果。似乎调用了 API,但价格从未更新。
这是我第一次处理异步函数和任务,所以我是这方面的新手。
protected async void Button1_Click(object sender, EventArgs e)
{
dt = DB_GetItemPrice();
for (int i = 0; i < dt.Rows.Count; i++)
{
var task = SendRequestAsync(dt.Rows[i]);
var items = await task;
Debug.WriteLine(task.Result);
}
}
protected async void Button2_Click(object sender, EventArgs e)
{
dt = DB_GetItemPrice();
var dr = dt.Rows[0];
var task = SendRequestAsync(dr);
var items = await task;
Debug.WriteLine(task.Result);
}
protected DataTable DB_GetItemPrice()
{
var db = PSystem.DataHelp.Database.Application;
var con = new DbConnection(db, ConnectionState.Open);
var st =
"SELECT * " +
"FROM item_discount ";
var cmd = new PSystem.DataHelp.DbCommand(st, con);
using (var reader = cmd.ExecuteReader())
{
var dt = PSystem.DataHelp.DbManager.GetDataTable(reader);
if (dt == null || dt.Rows.Count < 1)
return null;
return dt;
}
}
private async Task<string> SendRequestAsync(DataRow dr)
{
string APICall;
string OrderID = ((long)dr["OrderID"]).ToString();
string GoodsID = ((long)dr["GoodsID"]).ToString();
string NewPrice = ((long)dr["NewPrice"]).ToString();
Debug.WriteLine(OrderID + " ," + GoodsID + " ," + NewPrice);
APICall = "myAPIAdress?" + "&Param0=" + GoodsID + "," + 3 + "," + NewPrice + "," + 1 + "," + OrderID + ",,";
using (var wc = new System.Net.WebClient())
{
var Message = await wc.DownloadStringTaskAsync(APICall).ConfigureAwait(false);
return Message;
}
}
【问题讨论】:
-
循环不是并行的,您需要将这些任务存储在列表或类似的东西中,然后执行
Task.WhenAll。比如:var tasks = new List<Task<string>>(); await Tasks.WhenAll(tasks);。您将把任务添加到循环内的列表中,然后在循环外调用Tasks.WhenAll(tasks);。没有保证他们会完成的顺序,它会等到所有任务都完成。 -
我尝试按照您的建议将所有任务添加到列表中,但仍然没有成功。
protected async void Button1_Click(object sender, EventArgs e) { dt = DB_GetItemPrice(); for (int i = 0; i < dt.Rows.Count; i++) { var task = SendRequestAsync(dt.Rows[i]); activeTasks.Add(task); } await Task.WhenAll(activeTasks); } -
您的代码存在一些问题,可能需要先修复,因为它们可能是问题的一部分。就像打开多个连接但从不关闭它们一样。是“myAPIAdress”吗?占位符但不是真正的代码? DB_GetItemPrice 可以返回 null,但您需要一个有效的对象。
-
我只是不想透露 API 地址。那里还有另一个价值。我确定数据库不会返回 null。我可以看到所有 DataTable 在输出中返回它们的值。
Debug.WriteLine(OrderID + " ," + GoodsID + " ," + NewPrice);即使这些是导致问题的原因,我的 Button1_Click 也无法正常工作? -
异步不是那么容易,我建议你在没有异步的情况下检查你的代码,当功能正常时你迁移到异步
标签: c# asp.net async-await