c# - foreach vs Task.WhenAll() - 执行有什么不同吗?

标签 c# asynchronous async-await

在我的应用程序的管道上,有一个选项可以注入(inject)一组预请求处理程序,它可以在请求首次进入管道时改变请求。管道是完全异步的,因此必须等待这些预请求处理程序调用(以及其他一切)。我有几种不同的方式来调用这些处理程序,我想知道它们之间是否有任何区别,如果有的话,区别是什么?例如,是否会以相同的顺序调用各种处理程序?哪个选项可能提供最佳性能?

选项一:foreach

foreach (var handler in this.preRequestHandlers)
{
    await handler.Handle(request);
}

选项 2:ForEach()

this.preRequestHandlers.ForEach(async handler => await handler.Handle(request));

选项 3:Task.WhenAll()

await Task.WhenAll(this.preRequestHandlers.Select(handler => handler.Handle(request)));

最佳答案

假设您通过同时运行各个处理程序获益(您将知道这是否属实),选项 3 是最好的,因为它将在接近零的时间内创建任务集合,然后可能会并行执行,然后等待所有任务完成一次。选项 1 将依次、串行地执行每个处理程序。因此,如果每个处理程序需要 4 秒,并且同时运行多个处理程序仍需要约 4 秒,则选项 3 将在约 4 秒内完成。选项 1 将在 4 x(预请求处理程序的数量)秒内完成。

如果您需要处理程序按顺序执行,一个接一个,一次执行的处理程序不超过一个,则选项 3 不适合。

选项 2 并不适合任何情况,因为它将在处理程序任务完成之前完成。出于原因,请参阅任意数量的现有 SO 答案;例如:

How can I use Async with ForEach?

C# async await using LINQ ForEach()

Any point to List<T>.ForEach() with Async?

关于c# - foreach vs Task.WhenAll() - 执行有什么不同吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46844779/

相关文章:

javascript SetTimeout 仅在函数退出时调用

wpf - 在处理时更新 WPF UI - 异步等待的最佳使用

c# - 使用 System.Web.Optimization 时如何将类型 ="text/javascript"添加到脚本标记

c# - 在 Hangfire 仪表板中显示日志?

c# - 获取书签处的文本

.net - 从方法中将 BlockingCollection 作为 IEnumerable 返回

java - Spring @Async 每秒的速率

c# - 异步任务方法后触发回调

asynchronous - Haxe - 如何为 Flash 目标实现异步等待

C# 字符串表现得像 char 数组