async/await 创建新线程,输出窗口显示

Kev*_*Bui 5 c# asynchronous threadpool

我读过很多文章说 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");
}
Run Code Online (Sandbox Code Playgroud)

我在调试模式下启动应用程序,通过单击调试工具栏上的暂停按钮来暂停它。线程窗口显示只有一个主线程,到目前为止这是正常的。

在此输入图像描述

然后我单击按钮来执行methodAsync。当它完成 DownloadString 时,我再次暂停应用程序,然后我在线程窗口中看到几个附加线程。

在此输入图像描述

大约 10 秒后,输出窗口显示消息"The thread xxx has exited with code 0 (0x0)"

在此输入图像描述

WebClient.DownloadStringTaskAsync当我替换为时,结果相同await Task.Delay(xxx) ,我想知道 async/await 是否真的创建了新线程。

有什么解释吗?

Rau*_*ian 0

WebClient.DownloadStringTaskAsync方法使用基于任务的异步模式,并使用从线程池自动分配的资源线程资源

\n\n
\n

实现 TAP 方法时,您可以确定异步执行发生的位置。您可以选择在线程池上执行工作负载,通过使用异步 I/O 来实现它(对于大部分操作\xe2\x80\x99 的执行来说,无需绑定到\n 线程),在\n 特定线程(例如 UI 线程),或使用任意数量的\n 潜在上下文。

\n
\n\n

正如您在方法定义中看到的,它有一个属性,ExternalThreading = true表明它可以在外部线程上分配资源。

\n