尝试理解使用异步等待完成一些工作,而某些东西是行不通的。 有一个代码:
private async Task<string> getStringAsync()
{
var tsk = await Task.Run<string>(() =>
{
Task.Delay(2000);
return "helloWorld";
});
return tsk;
}
private void button2_Click(object sender, EventArgs e)
{
tbLog.Text += getStringAsync().Result;
}
问题是getStringAsync().Result
永远不会返回任何内容。
虽然根据文件它应该:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/await
我做错了什么?
答案 0 :(得分:3)
您正在使用Result
,它会阻止任务完成。您正在使用UI线程中的那个。因此UI线程将被阻止,直到任务完成。
现在,该任务来自getStringAsync
,它使用await (something)
。由于这种情况下的“某些东西”在等待的时候还没有完成(因为这是两秒钟的延迟),你说的是“当它完成时给我回电话”。但是因为你只是使用await
(没有ConfigureAwait(false)
),所以你说“在UI线程上给我回电话。”
所以你最终会遇到死锁:UI线程正在等待getStringAsync()
任务完成,但是在UI线程上执行回调之前,该任务无法完成
请注意,您的tsk
变量不是人们对名称所期望的任务 - 它是一个字符串,因为您正在等待Task<string>
。
最简单的解决方案是根本不使用Result
。相反,请创建事件处理程序async
并使用await
:
private async Task<string> GetStringAsync()
{
var text = await Task.Run(() =>
{
Task.Delay(2000);
return "helloWorld";
});
return text;
}
private async void HandleButton2Click(object sender, EventArgs e)
{
tbLog.Text += await GetStringAsync();
}