149

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

A:

IEnumerable<string> items = ...

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

乙:

IEnumerable<string> items = ...

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

使用其中一种会有不同的后果吗?(假设我在两个示例的括号中所做的任何事情都是线程安全的。)

4

3 回答 3

153

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

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

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

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

 var fibonacciNumbers = numbers.AsParallel().Select(n => ComputeFibonacci(n));
于 2010-09-24T18:51:53.797 回答
55

第二种方法不会并行,在您的示例中使用 AsParallel() 的正确方法是

IEnumerable<string> items = ...

items.AsParallel().ForAll(item =>
{
    //Do parallel stuff here
});
于 2010-09-24T19:15:50.027 回答
54

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

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

于 2010-09-24T19:01:26.170 回答