【发布时间】:2021-01-28 08:55:55
【问题描述】:
我有一个小项目 - WinForms 在 .net 框架上 - 只是一个小测试:
private void button9_Click(object sender, EventArgs e)
{
string text = GetTitleAsync().Result;
button9.Text = text;
}
private async Task<string> GetTitleAsync()
{
await Task.Delay(3000);
return "Hello!";
}
当我运行应用程序时, 单击按钮:“button9” - 导致死锁, (因为线程挂在“.result”上)
以这种方式编写 GetTitleAsync():
private async Task<string> GetTitleAsync()
{
await Task.Delay(3000).ConfigureAwait(false);
return "Hello!";
}
解决了死锁 - 应用程序运行正常。
但我不明白怎么做?
我曾预料到,使用“.ConfigureAwait(false)”会导致 情况:
"button9.Text = text;"在不同的线程上执行 在其上创建 UI 的那个, 并且会抛出异常!
但效果很好! 怎么样??
【问题讨论】:
-
Don't Block on Async Code -- 从那里删除
.ConfigureAwait(false);,更改:private async void button9_Click和string text = await GetTitleAsync(); -
ConfigureAwait(false);导致继续在不同的 Thread 上恢复,但WindowsFormsSynchronizationContext是 strong,第一个 await 将在用户界面线程。Result也是如此。但是你不会阻塞异步代码。 -
我还建议阅读 Stephen Cleary 关于该主题的帖子(第一条评论中的链接)。我还必须在这个答案中解释它:How ConfigureAwait(false) Prevent UI Deadlocks。您可能会发现它很有用。
标签: winforms async-await configureawait