异步和等待是单线程的吗? [英] async and await are single threaded Really?

查看:127
本文介绍了异步和等待是单线程的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了以下代码:

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

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

Which is fine but when I look in the Thread profiler its shows this: And then this: And then this:

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

So it looks like I spawn threads, but from msdn says:

使用Async和Await进行异步编程:线程

From Asynchronous Programming with Async and Await : Threads

async和await关键字不会导致其他线程成为 创建.异步方法不需要多线程,因为异步 方法不会在其自己的线程上运行.该方法在当前 同步上下文并仅在以下情况下在线程上使用时间 方法处于活动状态.您可以使用Task.Run将受CPU约束的工作移至 后台线程,但是后台线程对进程没有帮助 那只是在等待结果公布.

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.

我是想念东西还是不了解? 谢谢.

Am I missing or don't understanding something? Thanks.

推荐答案

我解释了如何await可以在我的博客上使用线程和上下文.总之,当await需要等待异步操作完成时,它将暂停"当前的async方法并(默认情况下)捕获上下文".

I explain how async and await work with threads and contexts on my blog. In summary, when await needs to wait for an asynchronous operation to complete, it will "pause" the current async method and (by default) capture a "context".

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

When the asynchronous operation completes, that "context" is used to resume the async method. This "context" is SynchronizationContext.Current, unless it is null, in which case it is TaskScheduler.Current. In your case, the context ends up being the thread pool context, so the rest of the async method is sent to the thread pool. If you run the same code from the UI thread, the context would be the UI context, and all the async methods will resume on the UI thread.

这篇关于异步和等待是单线程的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆