async 和 await 是单线程的真的吗?

async and await are single threaded Really?

我创建了以下代码:

using System;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main()
       {
         Console.WriteLine("M Start");
         MyMethodAsync();
         Console.WriteLine("M end");
         Console.Read();
       }

     static async Task MyMethodAsync()
     {
        await Task.Yield();
        Task<int> longRunningTask = LongRunningOperationAsync();
        Console.WriteLine("M3");
        //and now we call await on the task 
        int result = await longRunningTask;
        //use the result 
        Console.WriteLine(result);
     }

       static async Task<int> LongRunningOperationAsync()  
      {
        await Task.Delay(1000);
        return 1;
      }
  }
}

输出:

M Start
M end
M3
1

很好,但是当我查看线程分析器时,它显示如下: 然后这个: 然后这个:

所以看起来我生成了线程,但是从 msdn 说:

From Asynchronous Programming with Async and Await : Threads

The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active. You can use Task.Run to move CPU-bound work to a background thread, but a background thread doesn't help with a process that's just waiting for results to become available.

我是不是漏掉了或者不明白什么? 谢谢。

The async and await keywords don't cause additional threads to be created.

是的。它将 CPU 绑定或 I/O 绑定的工作从进程的线程池移动到其他线程,这样它就不会在 UI 线程或当前同步上下文中执行,它不会创建MSDN 描述中的新线程。

我在我的博客上解释 how async and await work with threads and contexts。综上所述,当await需要等待一个异步操作完成时,它会"pause"当前的async方法并且(默认)捕获一个"context".

异步操作完成后,"context"用于恢复async方法。这个 "context" 是 SynchronizationContext.Current,除非它是 null,在这种情况下它是 TaskScheduler.Current。在您的情况下,上下文最终成为线程池上下文,因此 async 方法的其余部分被发送到线程池。如果您 运行 来自 UI 线程的相同代码,上下文将是 UI 上下文,并且所有 async 方法将在 UI 线程上恢复.