我希望在阅读Asynchronous Programming with Async and Await (C# and Visual Basic)
后,我的GUI不会挂起 public async Task<string> DoBusyJob()
{
// Busy Job
Thread.Sleep(10000);
i++;
return "Finished " + i;
}
int i = 0;
private async void button1_Click(object sender, EventArgs e)
{
// Hang!
string result = await DoBusyJob();
this.label1.Text = result;
}
但事实并非如此。它仍然挂起。我意识到我需要在await
中添加额外的DoBusyJob
public async Task<string> DoBusyJob()
{
// Busy Job
await Thread.Sleep(10000);
i++;
return "Finished " + i;
}
int i = 0;
private async void button1_Click(object sender, EventArgs e)
{
// OK!
string result = await DoBusyJob();
this.label1.Text = result;
}
我可以知道为什么会这样吗?我真的需要加倍 await
吗?如果出现以下情况怎么办?
public async Task<string> DoBusyJob()
{
// How to prevent Hang?
for (int j = 0; j < 10000000; j++) {
double m = Math.Sqrt(1) + Math.Sqrt(2) + Math.Sqrt(3);
}
i++;
return "Finished " + i;
}
int i = 0;
private async void button1_Click(object sender, EventArgs e)
{
// Hang!
string result = await DoBusyJob();
this.label1.Text = result;
}
答案 0 :(得分:6)
有关async
方法的信息,请参阅the excellent answers to this question。
如果您没有使用已经异步的async
方法,则添加await
不足以使您的方法的执行异步。在这种情况下,您需要返回一个代表您的工作执行的Task
实例,例如。致电Task.Factory.StartNew
。
答案 1 :(得分:2)
async
/ await
FAQ中有一个很好的答案:
Q值。在方法上使用“async”关键字是否强制该方法的所有调用都是异步的?
一个。不。当您调用标记为“async”的方法时,它会在当前线程上开始同步运行...
Q值。 “async”关键字是否导致调用方法以排队到ThreadPool?要创建新线程?发射火箭飞往火星?
一个。不,不,不......
您可能会发现我的async
/ await
intro有帮助。
答案 2 :(得分:0)
我希望在将// OK!
添加到await
后,我能理解您的Thread.Sleep(10000);
无法等待方法Sleep()
返回void
只能在方法上指定其签名Task
或Task<TResult>
作为返回类型
异步方法在没有(或直到)await
的情况下同步执行,因此阻止了UI线程
await Task.Run()应立即返回(上一个)UI同步上下文,即继续下一个i ++;行执行
public async Task<string> DoBusyJob()
{
// Busy Job
await Task.Run(() =>
{
for (int j = 0; j < 10000000; j++)
{
double m = Math.Sqrt(1) + Math.Sqrt(2) + Math.Sqrt(3);
}
}
);
i++;
return "Finished " + i;
}