5

我正在尝试在带有 VS2012 框架 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;
}
4

1 回答 1

6

你造成了僵局。

使用task.Result会阻塞 UI 线程 - 在完成返回的任务之前它无法SlowMethodAsync完成。

但是,因为SlowMethodAsync最初也是在 UI 线程上使用同步上下文启动的,所以之后的继续await 想在 UI 线程上执行。

所以Result在异步方法完成之前无法完成......并且异步方法在完成之前无法Result完成。

相反,您应该使您的button1_Click方法也异步,然后使用:

Console.WriteLine("Slow method result on Thread: {0}", await task); 

这将在控制台应用程序中起作用的原因是该SlowMethodAsync方法没有任何特定的同步上下文可以返回,因此可以在任何线程池线程上执行延续 - 这不会被“主”阻塞线程等待任务。

于 2013-03-28T19:36:35.557 回答