繁体   English   中英

C#我如何平行IEnumerable的IEnumerable?

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

我有一个变量:

var contexts设置后是IEnumerable 这个对象的一个​​属性也是我有的IEnumerable

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

    });
});

但VS抱怨第二个ForEach

你试图在这里应用太多的嵌套并行性。

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

假设这是CPU绑定工作,你真的不想这样做。 这可能会创建太多需要映射到线程的任务,这将导致大量适得其反的上下文切换。

假设在最外层循环中具有相等卷的足够数量的项目,那么最好将并行性保持在外部循环:

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

(如果外环上的项目数不足以使所有内核保持忙碌,或者内部IEnumerable的项目分散不均匀并且会导致任务在不相等的时间内完成,那么请考虑使用@TheGeneral的使用思路contexts.SelectMany(c => c) ,即外形的形式outer.SelectMany(o => o.Inner) ,在并行化之前将嵌套集合展平为一个较大的集合。

如果仍然发现并发对于CPU绑定工作而言太高,则可以将其与目标计算机上的实际核心数相匹配,例如,如果您有8个可用核心:

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

但是,如果要将其用于IO绑定工作,那么Parallel.For* / .AsParallel是错误的工具 - 使用异步并行工具,如Task.WhenAll

暂无
暂无

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

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