我有一个小项目-- WinForms On .net frameWork --只是一个小测试:
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)“会导致以下情况:
“than on9.text= text;”在与创建UI的线程不同的线程上执行,并且将抛出一个excpetion!
但效果很好!怎么做??
发布于 2021-01-28 14:03:33
I本来以为,使用".ConfigureAwait(false)“会导致”.ConfigureAwait 9.Text= text;“在与创建UI的线程不同的线程上执行,并且会被抛出!但效果很好!怎么做??
我建议您阅读我的async/await intro;我尝试将您需要了解的关于async/await及其上下文的所有信息都包括在内,而不需要详细介绍。
具体而言,该职位有两点值得注意:
每个thread.
await方法都开始同步执行,除非使用ConfigureAwait(false).,否则调用将捕获上下文。
所以,我们来看看下面的代码:
private void button9_Click(object sender, EventArgs e)
{
string text = GetTitleAsync().Result;
button9.Text = text;
}
private async Task<string> GetTitleAsync()
{
await Task.Delay(3000).ConfigureAwait(false);
return "Hello!";
}这是按照顺序发生的,并特别注意哪个线程运行哪个代码:
button9_Click调用UI上的GetTitleAsync(),thread.GetTitleAsync()调用Task.Delay(3000)并返回一个将在3 seconds.GetTitleAsync() calls ConfigureAwait(false)中完成的任务,并返回一个配置好的侍者,该侍者将不再继续当前(UI) context.GetTitleAsync()使用await异步等待任务完成。此await将不会在当前(UI)上下文上恢复,因为await已配置为not。await检查任务并看到它不完成,因此它将一个不完整的Task<string>返回到其在该任务上的await calls .Result。这会阻塞UI线程,直到任务完成(即,executing).GetTitleAsync()就完成了,从Task.Delay(3000) completes.GetTitleAsync()返回的任务将在await之后恢复执行。因为这是一个配置好的await,所以它继续在线程池上执行,await返回"Hello!"。这是在线程池线程上完成的。GetTitleAsync()现在完成了,而它先前返回的Task<string>现在用结果值完成了。这个完成也发生在线程池thread.button9_Click.button9_Click在UI线程上执行button9.Text = text;。https://stackoverflow.com/questions/65933864
复制相似问题