异步/等待多核

本文关键字:多核 等待 异步 | 更新日期: 2023-09-27 18:20:04

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

异步/等待多核

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

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

如果您要查找的是并行处理,请查看Parallel类。

您还可以从阅读.NET Framework中的并行编程

开始

根据MSDN:

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

这就是它所做的一切。这与线程无关。它只会在同一个线程上开始做其他的事情,直到其他任务(而不是Task)完成。async/await也将在单核系统上实现单元前性能。

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;

这是连续运行的。

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

您可以使用类似PLINQ的东西在多个核心上进行工作。

参考:在多核处理器上运行查询