【问题标题】:Does "async" run in a separate thread? [duplicate]“异步”是否在单独的线程中运行? [复制]
【发布时间】:2020-01-26 11:56:13
【问题描述】:

当我调用 foo() 时,此方法是否在单独的线程上运行?

public async Task<bool> foo(){
  //Some code 
}

【问题讨论】:

  • 没有。 There is no thread
  • 请看下面post.
  • 取决于当前的线程 SynchronizationContext 以及您在该方法中执行的操作,尤其是您正在等待的其他异步调用以及如果您正在使用 .ConfigureAwait(false) 等待它们,它该方法可能在不同的线程上恢复(在等待之后),但它开始在调用者的线程上同步运行。

标签: c# task


【解决方案1】:

不,它没有。它可以在内部启动另一个线程并返回该任务,但总体思路是它不在任何线程上运行。

让我解释一下。 async 的一般用途是如果您不受 CPU 限制,这意味着 IO 和 windows 中的所有 IO 在最低级别都有回调操作接口,所以 - 网络请求发送请求然后继续工作 - 但没有线程随附的。完全没有。 async 的一般用例是 async 在线程上运行,当无事可做时,它将使用线程完成任务,允许在一个线程上进行多个操作 - 并且...... IO 不会用完线程.

您的方法基本上变成了状态引擎,将控制权交给任务调度程序,等待发出已完成任务的信号。

【讨论】:

    【解决方案2】:

    使用async 创建方法并不意味着它会创建另一个线程。如果CLR 发现您在async 方法中使用await 调用的方法 被延迟,则它将退出该方法并在等待的方法完成后等待,然后继续该方法与另一个线程。

    当您调用标记为async 的方法时,它开始在当前线程上同步运行。

    所以,结论是async 不会创建它自己的thread。调用方法的线程用于执行async方法,直到找到awaitable。然后,同一线程继续执行调用方法的其余部分,而不是 async 方法调用。在被调用的async 方法中,从等待返回后,可以在线程池中的一个线程上执行继续,这是唯一一个单独的线程出现的地方。

    【讨论】:

      【解决方案3】:

      不,这些任务并不意味着有一个单独的线程在运行。如果您的任务需要在其方法体中阻塞另一个异步任务,它可以在等待阻塞的资源时暂时返回执行,然后返回执行以完成任务。这基本上就是 await 关键字的用途。典型的异步任务是在真正的异步操作开始后等待 I/O 或网络资源返回数据的任务。您的方法本身也有可能产生自己的线程,使其异步,但它实际上仅取决于异步方法本身的实现。

      在此页面的“烹饪早餐类比”中可以找到很好的解释: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/

      请注意,可以并行运行任务,这可以产生单独的线程,但是当您直接调用方法时,默认情况下不会这样做。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-02
        • 1970-01-01
        相关资源
        最近更新 更多