最近,我看到了几个与Parallel.ForEach相关的SO线程与异步lambda混合在一起,但是所有提出的答案都是某种解决方法。
有什么办法可以写:
List<int> list = new List<int>[]();
Parallel.ForEach(arrayValues, async (item) =>
{
var x = await LongRunningIoOperationAsync(item);
list.Add(x);
});
如何确保列表将包含每个迭代中使用lambda执行的所有迭代中的所有项目?
通常Parallel.ForEach如何与异步lambdas一起使用,如果它等待命中,它将把其线程移交给下一个迭代吗?
我假设ParallelLoopResult IsCompleted字段不合适,因为在执行所有迭代时,无论其实际的lambda作业是否完成,它都将返回true。
最近,我看到了几个与Parallel.ForEach相关的SO线程与异步lambda混合在一起,但是所有提出的答案都是某种解决方法。
恩,那是因为Parallel
不适用于async
。从另一个角度来看,为什么要首先将它们混合?他们做相反的事情。Parallel
都是关于添加线程,而仅仅async
是放弃线程。如果要同时进行异步工作,请使用Task.WhenAll
。那是完成这项工作的正确工具。Parallel
不是。
就是说,听起来您想使用错误的工具,所以这里是您的操作方法...
如何确保列表将包含每个迭代中使用lambda执行的所有迭代中的所有项目?
您需要具有某种信号,某些代码可能会阻塞该信号,直到处理完成为止,例如CountdownEvent
或Monitor
。附带说明一下,您还需要保护对非线程安全的访问List<T>
。
通常Parallel.ForEach如何与异步lambdas一起使用,如果它等待命中,它将把其线程移交给下一个迭代吗?
由于Parallel
不了解async
lambda,因此当第一个await
产生(返回)其调用者时,Parallel
将假定循环已完成。
我假设ParallelLoopResult IsCompleted字段不合适,因为在执行所有迭代时,无论其实际的lambda作业是否完成,它都将返回true。
正确。据Parallel
了解,它只能“看到”await
返回给调用者的第一个方法。因此,它不知道async
lambda何时完成。它还将假定迭代完成得太早,这将导致分区失败。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句