我正在尝试在VS2012 Framework 4.5的表单上使用async和await命令。
我的异步方法SlowMethodAsync不返回任何内容。请注意,此代码在控制台应用程序中可以正常工作。
private void button1_Click(object sender, EventArgs e)
{
var task = SlowMethodAsync();
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}
System.Threading.Tasks.TaskStatus status = task.Status;
Console.WriteLine("Slow method result on Thread: {0}", task.Result); //This line never executes
Console.WriteLine("Main complete on {0}", Thread.CurrentThread.ManagedThreadId);
}
//Why is this method not returning anything?
static async Task<int> SlowMethodAsync()
{
Console.WriteLine("Slow method started on Thread: {0}", Thread.CurrentThread.ManagedThreadId);
await Task.Delay(2000);
Console.WriteLine("Slow method complete on Thread: {0}", Thread.CurrentThread.ManagedThreadId);
return 42;
}
最佳答案
您造成了僵局。
使用task.Result
会阻止UI线程-直到SlowMethodAsync
返回的任务完成后才能完成。
但是,由于SlowMethodAsync
最初是在UI线程上也是通过同步上下文启动的,因此await
之后的继续操作也要在UI线程上执行。
所以Result
在async方法完成之前无法完成...并且async方法在Result
完成之前无法完成。
相反,您也应该使button1_Click
方法也异步,然后使用:
Console.WriteLine("Slow method result on Thread: {0}", await task);
之所以可以在控制台应用程序中工作,是因为
SlowMethodAsync
方法没有任何特定的同步上下文可以返回,因此该延续可以在任何线程池线程上执行-不会被“主线程”阻塞线程正在等待任务。