.net 异步等待,我做错了什么
.net async await, what I am doing wrong
试图了解使用 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
从来没有 returns 任何东西。
尽管根据文档它应该:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/await
我做错了什么?
您正在使用 Result
,它会阻塞直到任务完成。您正在使用 UI 线程中的那个。因此 UI 线程将被阻塞,直到任务完成。
现在,该任务来自 getStringAsync
,它使用 await (something)
。由于 "something" 在这种情况下不会在等待时完成(因为它有两秒的延迟),所以你说 "Call me back when that's finished." 但是因为你只是在使用 await
(没有 ConfigureAwait(false)
),你说的是 "call me back on the UI thread".
所以你最终遇到了死锁: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();
}
试图了解使用 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
从来没有 returns 任何东西。
尽管根据文档它应该:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/await
我做错了什么?
您正在使用 Result
,它会阻塞直到任务完成。您正在使用 UI 线程中的那个。因此 UI 线程将被阻塞,直到任务完成。
现在,该任务来自 getStringAsync
,它使用 await (something)
。由于 "something" 在这种情况下不会在等待时完成(因为它有两秒的延迟),所以你说 "Call me back when that's finished." 但是因为你只是在使用 await
(没有 ConfigureAwait(false)
),你说的是 "call me back on the UI thread".
所以你最终遇到了死锁: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();
}