简体   繁体   English

C#我如何平行IEnumerable的IEnumerable?

[英]C# how do I parallellize an IEnumerable of IEnumerable?

I have a variable: 我有一个变量:

var contexts where after setting is an IEnumerable . var contexts设置后是IEnumerable One of the properties on this object is also an IEnumerable I have: 这个对象的一个​​属性也是我有的IEnumerable

Parallel.ForEach(contexts.AsParallel(), (context) =>
{
    Parallel.ForEach(context, (child) =>
    {

    });
});

but VS complains about the second ForEach 但VS抱怨第二个ForEach

You're trying to apply way too much nested parallelism here. 你试图在这里应用太多的嵌套并行性。

Parallel.ForEach(   <-- #1
     contexts.AsParallel(), <-- #2
         (context) =>  {
        Parallel.ForEach( <- #3

Assuming this is CPU bound work, you really don't want to be doing this. 假设这是CPU绑定工作,你真的不想这样做。 This will potentially create too many Tasks which will need to be mapped onto threads, which will cause lots of counter-productive context switching. 这可能会创建太多需要映射到线程的任务,这将导致大量适得其反的上下文切换。

Assuming a sufficient number of items at the outermost loop with equal volumes, then it is better to just keep the parallelism at the outer loop: 假设在最外层循环中具有相等卷的足够数量的项目,那么最好将并行性保持在外部循环:

Parallel.ForEach(
  contexts, 
  context => { ...

(And if the number of items on the outer loop is insufficient to keep all cores busy, or if the item dispersion in the inner IEnumerable isn't even and will cause tasks to complete at unequal times, then consider using @TheGeneral's idea of using contexts.SelectMany(c => c) , ie of the form outer.SelectMany(o => o.Inner) , to flatten the nested collections into one larger one, before parallelising). (如果外环上的项目数不足以使所有内核保持忙碌,或者内部IEnumerable的项目分散不均匀并且会导致任务在不相等的时间内完成,那么请考虑使用@TheGeneral的使用思路contexts.SelectMany(c => c) ,即外形的形式outer.SelectMany(o => o.Inner) ,在并行化之前将嵌套集合展平为一个较大的集合。

If you still find that concurrency is too high for CPU-bound work, you can match it to the number of actual cores on the target computer, eg if you have 8 cores available: 如果仍然发现并发对于CPU绑定工作而言太高,则可以将其与目标计算机上的实际核心数相匹配,例如,如果您有8个可用核心:

Parallel.ForEach(
  contexts, 
  new ParallelOptions { MaxDegreeOfParallelism = 8 },  
  context => { ...

However, if this is to be used for IO bound work, then Parallel.For* / .AsParallel are the wrong tools - use an asynchronous parallelism tool such as Task.WhenAll . 但是,如果要将其用于IO绑定工作,那么Parallel.For* / .AsParallel是错误的工具 - 使用异步并行工具,如Task.WhenAll

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM