简体   繁体   中英

C# how do I parallellize an IEnumerable of IEnumerable?

I have a variable:

var contexts where after setting is an IEnumerable . One of the properties on this object is also an IEnumerable I have:

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

    });
});

but VS complains about the second 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. 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).

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:

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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