异步/等待多核
本文关键字:多核 等待 异步 | 更新日期: 2023-09-27 18:20:04
异步/等待是否应该与线程一起使用以利用多核?我不完全理解async/await,但看起来它没有创建新的线程,也没有使用线程池。所以它在当前线程上运行代码,这意味着没有多核支持。
async-await
不是关于跨多个核心的负载平衡工作。这是关于利用本质上异步的操作,并释放资源来处理更多的工作。好的异步API不使用额外的线程来执行工作。通常,没有线程,这意味着代码将继续在同一线程上执行,直到到达第一个await
并将控制权交还给调用者。
您可以查看异步API的示例,如HttpClient
、StreamWriter
、SmtpClient
等。它们都通过有线处理工作(网络驱动程序调用、磁盘驱动器调用等)。
如果您要查找的是并行处理,请查看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的东西在多个核心上进行工作。
参考:在多核处理器上运行查询