调用Task.Result时Windows窗体中断

Tom*_*rek 3 c# winforms async-await

我的代码类似于以下Windows窗体中的代码:

private async Task<string> GetGreetingAsync()
{
    return await Task.Run(() => "Hello");
}

private void button1_Click(object sender, EventArgs e)
{
    var x = GetGreetingAsync().Result;
}
Run Code Online (Sandbox Code Playgroud)

单击该按钮会导致整个Windows窗体冻结并无响应.没有异常被抛出.

即使我没有.Result直接在事件处理程序中使用任务,并且整个async标记的代码在某些类库函数中,它提供了接口async,但问题仍然存在.这种类库的单元测试没有任何问题,但是当我从Windows窗体上的事件处理程序调用它的函数时,它会中断并且不响应.

为什么会这样?我该如何解决?

L.B*_*L.B 9

您正在阻止UI线程.Result;(请参阅ConfigureAwait)

private async Task<string> GetGreetingAsync()
{
    return await Task.Run(() => "Hello").ConfigureAwait(false);
}

private void button1_Click(object sender, EventArgs e)
{
    var x = GetGreetingAsync().Result;
}
Run Code Online (Sandbox Code Playgroud)

或者一路走异步

private async Task<string> GetGreetingAsync()
{
    return await Task.Run(() => "Hello");
}

async private void button1_Click(object sender, EventArgs e)
{
    var x = await GetGreetingAsync();
}
Run Code Online (Sandbox Code Playgroud)

使用这个版本中,你甚至都不需要等待GetGreetingAsync

private Task<string> GetGreetingAsync()
{
    return Task.Run(() => "Hello");
}

async private void button1_Click(object sender, EventArgs e)
{
    var x = await GetGreetingAsync();
}
Run Code Online (Sandbox Code Playgroud)

  • @tomp,stephen cleary在这里解释它:http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html (3认同)