Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# async和await真的是单线程的吗?_C#_.net_Multithreading_Async Await_Task - Fatal编程技术网

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

C# async和await真的是单线程的吗?,c#,.net,multithreading,async-await,task,C#,.net,Multithreading,Async Await,Task,我创建了以下代码: using System; using System.Threading.Tasks; namespace ConsoleApplication2 { class Program { static void Main() { Console.WriteLine("M Start"); MyMethodAsync(); Console.WriteLine("M end");

我创建了以下代码:

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;
      }
  }
}
这很好,但当我查看线程探查器时,它显示: 然后这个: 然后这个:

所以看起来我产生了线程,但msdn说:

从异步编程到异步和等待:线程

async和await关键字不会导致添加额外的线程 创建。异步方法不需要多线程,因为异步 方法不在自己的线程上运行。该方法在当前服务器上运行 同步上下文,并且仅当 方法处于活动状态。您可以使用Task.Run将CPU绑定的工作移动到 后台线程,但后台线程对进程没有帮助 那只是等待结果出来

我是错过了什么还是不明白? 谢谢

async和await关键字不会导致创建其他线程

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

我在博客上解释。总之,当
await
需要等待异步操作完成时,它将“暂停”当前
async
方法,并(默认情况下)捕获“上下文”


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

它使用线程池中的现有线程,而不是创建一个看起来像Visual Studio中非常漂亮的窗口的线程。很抱歉这个离题的问题,但是哪个版本支持它?用
Thread.CurrentThread.ManagedThreadId
装饰您的输出,您可能会看到正在使用3个线程。@GediminasMasait是
并行堆栈
任务
视图,我认为这两个视图都添加到VS 2013中。它们都可以在
Debug->Windows
下拉菜单下找到。@DinkarThakur,有点与您的问题相关,但您可能有兴趣阅读Stepen Cleary的博文“”。它深入地观察了当您等待一个基于IO的请求时发生的情况。但如果所有线程都被消耗,那么它将等待。对吗?这是错误的。任务在当前同步上下文上执行。只有在使用基于线程池的同步上下文时,才会使用不同的线程,否则所有操作都是在带有队列的主线程上完成的。阅读“延续传递样式”,这是异步如何在下面工作的。
M Start
M end
M3
1