【发布时间】:2018-06-18 15:37:38
【问题描述】:
我正在编写 Windows 窗体应用程序,但在从 FTP 服务器加载数据时遇到了阻塞 UI 的问题。
我有一个从中获取信息的服务器列表。因此,当我单击“从所有人中获取”按钮时,我会从每个人那里获取信息。
private void GetInfoToolStripMenuItem_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow row in infoDataGridView.Rows)
this.GetInfoAsync(row);
}
我在从服务器获取信息时运行新任务以防止 UI 阻塞。 GetInfo 方法是异步的:
private async void GetInfoAsync(DataGridViewRow row)
{
Server server = (Server)row.Cells[0].Value;
row.Cells[1].Value = Resources.GettingIcon;
await Task.Run(() =>
{
server.Data = dataGetter.GetData(server);
});
row.Cells[1].Value = Resources.FinishedIcon;
}
主要问题是:为什么 foreach 在 GetInfoAsync 完成之前开始新的迭代?我在这个方法中使用了 await 关键字,所以在数据完成之前执行不应该完成。
【问题讨论】:
-
你没有
awaitGetInfoAsync。 -
您没有在 click 事件处理程序中使用 await,它们都是一劳永逸的。
-
@Servy "主要问题是:为什么 foreach 在 GetInfoAsync 完成之前开始新的迭代?"
-
@Servy
The main question is: why foreach starts new iteration before GetInfoAsync finished? -
GetInfoAsync是一种即发即弃的方法,async void,它不返回任务。但是,它会在第一次遇到await T时立即返回,其中T是在您尝试等待它时尚未完成的任务,这是您代码中的Task.Run部分。因此,您的循环将调用GetInfoAsync,它将执行直到您开始另一个任务,然后返回到您的循环。如果您想在继续循环之前完成此异步方法,请将其更改为async Task并在循环中等待它。
标签: c# winforms asynchronous multitasking