Parallel.ForEach()与foreach(IEnumerable <T> .AsParallel())

Sni*_*ave 140 .net c# parallel-processing multithreading parallel.foreach

Erg,我正在尝试使用Reflector在BCL中找到这两个方法,但找不到它们.这两个片段之间的区别是什么?

A:

IEnumerable<string> items = ...

Parallel.ForEach(items, item => {
   ...
});
Run Code Online (Sandbox Code Playgroud)

B:

IEnumerable<string> items = ...

foreach (var item in items.AsParallel())
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

使用一个比另一个有不同的后果吗?(假设我在两个示例的括号内部所做的事情都是线程安全的.)

小智 147

他们做的事情完全不同.

第一个采用匿名委托,并在所有不同的项目上并行运行此代码的多个线程.

第二个在这种情况下不是很有用.简而言之,它旨在对多个线程进行查询,并组合结果,并将其再次提供给调用线程.因此,foreach语句中的代码始终位于UI线程上.

只有在AsParallel()调用右侧的linq查询中执行一些昂贵的操作才有意义,例如:

 var fibonacciNumbers = numbers.AsParallel().Select(n => ComputeFibonacci(n));
Run Code Online (Sandbox Code Playgroud)


svi*_*ick 50

不同的是,B不是平行的.唯一AsParallel()能做的就是它包装了一个IEnumerable,所以当你使用LINQ方法时,会使用它们的并行变体.包装器GetEnumerator()(在幕后使用foreach)甚至返回原始集合的结果GetEnumerator().

顺便说一句,如果你想看一下Reflector中的方法,AsParallel()就是在程序集中的 System.Linq.ParallelEnumerable类中System.Core.Parallel.ForEach()mscorlib程序集(命名空间System.Threading.Tasks)中.

  • @punctuation例如,当您编写`.Select()`时,它调用`ParallelEnumerable.Select()`而不是正常的`Enumerable.Select()`. (2认同)

Sco*_*ain 49

第二种方法不是平行的,在你的例子中使用AsParallel()的正确方法

IEnumerable<string> items = ...

items.AsParallel().ForAll(item =>
{
    //Do parallel stuff here
});
Run Code Online (Sandbox Code Playgroud)

  • 为什么使用asparallel和forall的组合而不仅仅是foreach? (3认同)