简体   繁体   English

等待创建另一个线程吗?

[英]Does await create another thread?

I read the Microsoft document about async and await. 我阅读了有关异步并等待的Microsoft文档 It says: 它说:

The async and await keywords don't cause additional threads to be created. async和await关键字不会导致创建其他线程。

But I run the below code 但是我运行下面的代码

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

namespace Examples.AdvancedProgramming.AsynchronousOperations
{
    public class AsyncMain
    {
        static void Main()
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
            Task task = Test();
            task.Wait();
        }

        public async static Task Test()
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
            await Task.Delay(1000);
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
        }

    }
}

The result is 结果是

1 1个
1 1个
4 4

It is obvious that the 很明显,

await Task.Delay(1000);
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);

is run in another thread. 在另一个线程中运行。 Why does the document says there is no thread created? 为什么文档说没有创建线程?

I have read the previous question Does the use of async/await create a new thread? 我已经阅读了上一个问题,使用async / await是否会创建一个新线程? , but it does not answer my question, the answer there just copy pastes from a Microsoft source. ,但它不能回答我的问题,那里的答案只是从Microsoft来源复制粘贴。 Why do I see different thread IDs in my test? 为什么在测试中看到不同的线程ID?

I always encourage people to read my async intro , and follow up with async best practices . 我总是鼓励人们阅读我的async介绍 ,并跟进async最佳实践 In summary: 综上所述:

await by default captures a "context", and resumes executing the async method in that context. 默认情况下, await捕获“上下文”,并在该上下文中继续执行async方法。 In this case, the context is the thread pool context. 在这种情况下,上下文是线程池上下文。 So, that's why you're seeing Test resume executing on a thread pool thread. 因此,这就是为什么您看到Test恢复在线程池线程上执行的原因。

async and await by themselves do not create any additional threads; asyncawait本身不会创建任何其他线程; if you do the same in a UI app, for example, the "context" would be the UI thread, and Test would resume executing on that UI thread. 例如,如果您在UI应用程序中执行相同的操作,则“上下文”将是UI线程,而Test将继续在该UI线程上执行。 But the context that is implicitly captured by await is what is responsible for scheduling the asnc continuation, and the context in this example just schedules it to the thread pool. 但是由await隐式捕获的上下文负责调度asnc连续,并且在此示例中,上下文只是将其调度到线程池。

You see different thread IDs in your test because different threads were used to execute your code. 您在测试中看到了不同的线程ID,因为使用了不同的线程来执行代码。 That does not mean the async/await caused the creation of additional threads. 这并不意味着异步/等待导致了其他线程的创建。 In this case, the threads used already existed in a pool of threads called the thread pool. 在这种情况下,使用的线程已经存在于称为线程池的线程池中。

There are two distinct ideas: 有两个不同的想法:

  • tasks representing the work to be done, and 代表要完成的工作的任务, 以及
  • how the tasks are actually processed (eg scheduled and executed) 如何实际处理任务(例如计划和执行)

Async/await relate to the former but your test code is telling you something about the latter: the specific mechanism by which those tasks have been processed. Async / await与前者有关,但是您的测试代码告诉您有关后者的信息:处理这些任务的特定机制。

The mechanism is determined by the context. 该机制由上下文决定。 Some contexts use more than one thread (but note it is up to the context to decide how it manages those threads, including whether and when it creates new ones) but some only use 1 thread. 一些上下文使用多个线程(但是请注意,上下文取决于它如何管理这些线程,包括是否以及何时创建新线程),但某些上下文仅使用1个线程。

That more than one thread was used is to do with the context, not the async/await. 使用了多个线程是与上下文有关的,而不是异步/等待。

I changed your example a bit: 我改变了你的例子:

public async static Task Test()
{
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
    await Task.CompletedTask; // <--- instead of Task.Delay()
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
}

Now the output is 1, 1, 1. 现在输出为1、1、1。

The await is not creating the new thread. await未创建新线程。 The Task.Delay is the culprit! Task.Delay是元凶!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM