【问题标题】:Async/await multi core异步/等待多核
【发布时间】:2014-08-31 12:11:22
【问题描述】:

async/await 是否应该与线程一起使用以利用多核?我不完全理解 async/await,但看起来它不会创建新线程并且不使用线程池。所以它在当前线程上运行代码,这意味着不支持多核。

【问题讨论】:

  • Async/await 本身与线程无关。它是关于暂停执行等待结果,并为其他代码释放资源。线程是这个特性的一种外部:实现可能决定切换到另一个线程来执行任务。 (Task.Run 也将使用线程池线程 AFAIK。但它与 async/await 功能没有直接关系。)
  • 正确。它是关于 IO 池,而不是线程池。

标签: c# .net async-await


【解决方案1】:

async-await 不是关于跨多个内核的负载平衡工作。它是关于利用本质上是异步的操作并释放资源来处理更多的工作。好的异步 API 不会使用额外的线程来执行工作。通常是There is no Thread,这意味着代码将继续在同一个线程上执行,直到遇到第一个await 并将控制权交还给调用者。

您可以查看异步 API 的示例,例如 HttpClientStreamWriterSmtpClient 等。它们都通过网络处理工作(网络驱动程序调用、磁盘驱动器调用等)。

如果您正在寻找并行处理,请查看 Parallel 类。

你也可以先阅读Parallel Programming in the .NET Framework

【讨论】:

  • 如果没有线程,那么为什么下面问题的第二个答案中显示的 C# 示例演示了异步等待产生多个线程? stackoverflow.com/questions/38865050/…
  • @AjaxLeung 因为当您在控制台应用程序中使用Task.Delay 时,备份同步上下文的是线程池,它只是在任意线程上恢复执行。不会产生任何线程 在 WinForm 应用程序中尝试相同的示例。
【解决方案2】:

根据MSDN

await 运算符应用于异步方法中的任务,以暂停该方法的执行,直到等待的任务完成。任务代表正在进行的工作。

就是这样。它根本与线程无关。它只会开始在同一线程上执行其他操作,直到其他任务(不是Task)完成。 async / await 也将提高单核系统的性能。

【讨论】:

    【解决方案3】:

    await 没有任何内在的强制非并行执行。您可以轻松启动多个任务,并行运行它们并同时等待它们。

    await 确实确保async 方法在活动的环境同步上下文中运行。这通常会导致非并行执行。所有主流同步上下文都是非并行的。您可以使用Task.Run 随意突破该限制。

    也就是说,在 GUI 应用程序中,您不需要在 UI 线程上并行执行,因为您根本不应该在那里做太多工作。

    在服务器应用程序中,同步上下文是单线程每个请求。这也是一个很好的默认值。不同的请求并行运行。

    再说一次,你可以随意爆发:

    var t1 = Task.Run(...);
    var t2 = Task.Run(...);
    await t1;
    await t2;
    

    这是并行运行的。

    var t1 = Task.Run(...);
    await t1;
    var t2 = Task.Run(...);
    await t2;
    

    这是串行运行的。

    【讨论】:

      【解决方案4】:

      如果您尝试像那样使用 async/await,它只会启动一个新线程,但它不能用于在多个内核上运行某些东西。工作只是简单地转移到另一个线程并释放当前线程。

      您可以使用 PLINQ 之类的东西来处理多个内核。

      参考:Running Queries On Multi-Core Processors

      【讨论】:

      • 严格来说,async/await 不会启动一个新线程,它是一个 Task-impleneting 方法。
      • @Vlad:好点子,我改写了那部分以尽量避免这种区别。
      • @Vlad:不够好?你真的认为这个答案因为一个不相关的细节而值得否决吗?
      • “async/await 通常会启动一个新线程”的确认不相关?我读过一些文档另有说明,所以对我来说至少是令人困惑的。
      • 我从来没有听说过标准框架异步函数启动一个新线程甚至一个新任务。它们通常是使用其他异步调用方式的 IO 方法,例如 IOCP。
      猜你喜欢
      • 1970-01-01
      • 2023-03-12
      • 2018-12-02
      • 1970-01-01
      • 2016-07-07
      • 2016-03-25
      • 2017-10-09
      相关资源
      最近更新 更多