在我的应用程序的管道上,有一个选项可以注入(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# - foreach vs Task.WhenAll() - 执行有什么不同吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46844779/