我有一个方法,其中有一个 foreach 循环,在循环内我调用了几个异步操作。我让 ChatGPT 做了审查,他说可以通过将任务添加到列表中并调用 Task.WhenAll() 来提高性能。
foreach (var name in names)
{
var some = await SomeMethodAsync1(name);
await SomeMethodAsync2(name);
...
}
重做:
var tasks = names.Select(async n =>
{
var some = await SomeMethodAsync1(n);
await SomeMethodAsync2(n);
...
}).ToList();
await tasks.WhenAll();
我不明白为什么这更有效率?毕竟我也是在Select里面用await调用异步方法,那和简单的循环有什么区别呢?
foreach
循环在每次迭代时等待。因此,每次迭代都会在前一次迭代完成后开始,并且对 SomeMethodAsync1
和 SomeMethodAsync2
的所有调用都将针对每次迭代单独(连续)完成。
当您执行
Select
时,它会启动代表您定义的 async
lambda 的任务,并且现在并行处理数组中的每个项目。
现在拥有代表并行工作的所有任务,您可以使用
WhenAll()
方法来等待所有任务。
第一个示例对每个名称依次运行处理代码,而第二个示例则启动所有代码,而不等待其他名称完成。
这是否是一种改进取决于您处理每个名称的内容和方式。