【发布时间】:2018-06-30 05:10:50
【问题描述】:
我读过很多文章说 async/await 不会创建额外的线程。 但是 Visual Studio 调试模式下输出和线程窗口的消息却相反。
我用一些代码创建了一个非常简单的示例窗体;
private void button2_Click(object sender, EventArgs e)
{
Task t = methodAsync();
//t.Wait();
}
async Task methodAsync()
{
Console.WriteLine($"==before DownloadStringTaskAsync");
using (var wc = new System.Net.WebClient())
{
string content = await wc.DownloadStringTaskAsync("https://stackoverflow.com");
}
Console.WriteLine($"==after DownloadStringTaskAsync");
}
我在调试模式下启动应用程序,我通过单击调试工具栏上的暂停按钮来暂停它。线程窗口显示只有一个主线程,目前正常。
然后我点击按钮执行methodAsync。完成 DownloadString 后,我再次暂停应用程序,然后在线程窗口中看到几个附加线程。
大约 10 秒后,输出窗口显示消息 "The thread xxx has exited with code 0 (0x0)"。
当我将WebClient.DownloadStringTaskAsync 替换为await Task.Delay(xxx) 时,结果相同
我想知道 async/await 是否真的创建了新线程。
有什么解释吗?
【问题讨论】:
-
异步工作通常会在不同的线程上运行,但如果您不使用 ConfigureAwait(false),它将在原始线程上恢复。它正在从池中抓取一个线程。我不确定这是否是您所说的“创建线程”。
-
你读到的和你理解的不一定是一回事。
await-async并不自动意味着在“新线程”中运行此任务,在某些情况下它会在某些情况下不会。要理解的想法是异步与另一个线程上的并发不同。 -
@Fabjan 并非总是如此。并非所有异步任务都需要在线程池中的线程上运行。看看there is no thread 以获得有趣的阅读。
-
如果您还不知道,请查看“调试”>“窗口”>“任务”窗格。
-
@fabjan 题外话,你的断言是不正确的,我只是指出来。
标签: c# asynchronous threadpool