我为什么要获得WaitingforActivation TaskStatus

时间:2013-03-28 19:33:22

标签: c#

我正在尝试在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;
}

1 个答案:

答案 0 :(得分:5)

你已经陷入僵局。

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

但是,由于SlowMethodAsync最初也是在UI线程上同步上下文启动的,因此await 之后的继续也希望在UI线程上执行。

因此,在异步方法完成之前,Result无法完成...并且在Result完成之前无法完成异步方法。

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

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

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