【发布时间】:2020-02-24 00:50:36
【问题描述】:
最近我看到几个与 Parallel.ForEach 相关的 SO 线程与异步 lambda 混合,但所有建议的答案都是某种解决方法。
有什么办法可以写:
List<int> list = new List<int>[]();
Parallel.ForEach(arrayValues, async (item) =>
{
var x = await LongRunningIoOperationAsync(item);
list.Add(x);
});
如何确保列表包含每次迭代中使用 lambdas 执行的所有迭代中的所有项目?
Parallel.ForEach 通常如何与异步 lambda 一起工作,如果它命中 await 是否会将其线程移交给下一次迭代?
我假设 ParallelLoopResult IsCompleted 字段不是正确的,因为它会在所有迭代执行时返回 true,无论它们的实际 lambda 作业是否完成?
【问题讨论】:
-
await 将强制释放任务线程,并且它不保证在等待的任务完成时同一线程将继续。但是是的,Parallel ForEach 将保证所有迭代都完成并且 x 被添加到列表中,除非发生异常。
-
您最好使用
var results = await Task.WhenAll(arrayvalues.Select(x => LongRunningIoOperationAsync(x)))。 Parallel 更适合 CPU 密集型工作,而不是 IO 密集型。 -
您的实现不是线程安全的。您不能在
Parallel.ForEach内调用list.Add(x)。 -
@ldragicevic 如果你想限制并发异步操作的数量,请查看here。
标签: c# task-parallel-library parallel.foreach