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

时间:2018-01-21 12:40:34

标签: c# asynchronous threadpool

我读过很多文章说async / await没有创建额外的线程。 但是Visual Studio的调试模式中的输出和线程窗口的消息却反过来说。

我用一些代码创建了一个非常简单的Windows窗体示例;

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");
}

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

enter image description here

然后我点击按钮执行methodAsync。当它完成DownloadString时,我再次暂停app,然后我在Thread窗口中看到了几个额外的线程。

enter image description here

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

enter image description here

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

任何解释?

2 个答案:

答案 0 :(得分:1)

asyncawait只是生成方法awaitable的关键字,然后允许您异步等待它并继续执行。 Tasks是表示方法执行的异步结果的底层框架元素,TaskScheduler负责协调Tasks的执行,这可能涉及使用线程池,创建新线程, Windows上的默认任务计划程序通常使用线程池来执行任务。

答案 1 :(得分:0)

WebClient.DownloadStringTaskAsync方法使用Task-based Asynchronous Pattern并使用从线程池自动分配的资源线程资源。

  

实现TAP方法时,可以确定异步位置   执行发生。您可以选择在线程上执行工作负载   pool,使用异步I / O实现它(不受绑定   线程为大多数操作的执行),在一个上运行它   特定线程(如UI线程),或使用任意数量的   潜在的背景。

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