.net异步等待,我做错了什么

时间:2017-07-21 21:54:13

标签: .net asynchronous async-await

尝试理解使用异步等待完成一些工作,而某些东西是行不通的。 有一个代码:

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

我做错了什么?

1 个答案:

答案 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();
}