Parallel.ForEach()与foreach(IEnumerable <t> .AsParallel())</t>

时间:2010-09-24 18:45:29

标签: c# .net multithreading parallel-processing parallel.foreach

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

A:

IEnumerable<string> items = ...

Parallel.ForEach(items, item => {
   ...
});

B:

IEnumerable<string> items = ...

foreach (var item in items.AsParallel())
{
   ...
}

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

3 个答案:

答案 0 :(得分:145)

他们做了一些完全不同的事情。

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

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

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

 var fibonacciNumbers = numbers.AsParallel().Select(n => ComputeFibonacci(n));

答案 1 :(得分:49)

不同的是,B不是平行的。 AsParallel()做的唯一事情是它包裹IEnumerable,因此当您使用LINQ方法时,会使用它们的并行变体。包装器的GetEnumerator()(在foreach中的幕后使用)甚至会返回原始集合GetEnumerator()的结果。

顺便说一句,如果您想查看Reflector中的方法,AsParallel()位于System.Linq.ParallelEnumerable程序集中的System.Core类中。 Parallel.ForEach()位于mscorlib程序集(名称空间System.Threading.Tasks)。

答案 2 :(得分:47)

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

IEnumerable<string> items = ...

items.AsParallel().ForAll(item =>
{
    //Do parallel stuff here
});