我正在尝试在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方法没有任何特定的同步上下文可以返回,因此该延续可以在任何线程池线程上执行-不会被“主线程”阻塞线程正在等待任务。

10-02 13:22