【问题标题】:does async use worker thread from the threadpool? [duplicate]异步是否使用线程池中的工作线程? [复制]
【发布时间】:2020-10-27 00:23:02
【问题描述】:

我是 C# 和异步编程的新手,如果我的问题听起来很愚蠢,我很抱歉。 假设我们有以下代码:

static void Main()
{
    SomeMethod();
    Console.WriteLine("Main program almost finishes");
    Console.ReadLine();
}

static async void SomeMethod()
{
    await Task.Delay(4000);
    Console.WriteLine("Asnc code finished");
}

我对@9​​87654324@的理解,这个工作单元在线程池中排队等待一个工作线程去执行,所以延迟发生在工作线程(这个工作线程睡眠4s)和一次4s过去了,那么这个工作线程继续执行下面的语句Console.WriteLine("Asnc code finished");,我的理解对吗?

【问题讨论】:

  • There is no thread 主要是从 I/O 的上下文中编写的,但重点仍然存在。 没有要求我们拥有一个线程来纯粹阻塞它。
  • @Damien_The_Unbeliever 听起来如果是 IO 绑定操作则没有线程,但如果我将 await Task.Delay(4000); 更改为 Task.Run() 运行 CPU 绑定操作,例如对前 10000 个整数求和, CPU 可能需要 5s 来执行它,那么工作线程应该启动吗?
  • 如果您使用Task.Run 而不是 要求工作线程运行一些代码。无论您是否使用await,都是如此。请注意,await 会按照它所说的去做——它会等待。它绝不负责创建任务或分配线程。
  • 顺便说一句 async void 应该只用于异步事件处理程序。它不能等待。您的应用程序将在计时器有机会触发之前终止

标签: c# .net


【解决方案1】:

在谈论异步时,有一种叫做“上下文”的东西。通常有两个上下文,“UI”上下文和“背景”上下文。前者代表主/UI线程,后者代表任意线程池线程。

您的示例看起来像一个控制台程序,因此它没有 UI 线程/上下文。

await 将在您当前使用的相同上下文中恢复执行。 IE。如果您在 UI 线程上,等待之后的所有内容也将在主线程上。如果您不在 UI 线程上,您将继续在线程池线程上执行(但不一定与等待之前的线程相同)。

您正在等待的任务可能使用线程池线程、UI 线程或根本不使用线程。这完全取决于创建任务的人。

默认情况下Task.Run 将使用线程池线程,但可以使用具有其他行为的其他任务调度程序启动任务。

【讨论】:

    猜你喜欢
    • 2017-06-20
    • 2010-12-22
    • 1970-01-01
    • 2023-01-25
    • 2015-07-13
    • 1970-01-01
    • 1970-01-01
    • 2018-03-02
    • 2018-01-20
    相关资源
    最近更新 更多