ForEach() vs ForEach (IEnumable < T > . AsParall())

额,我试图在 BCL 中使用反射器找到这两个方法,但是找不到它们。这两个片段有什么区别?

答:

IEnumerable<string> items = ...


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

乙:

IEnumerable<string> items = ...


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

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

75573 次浏览

它们的作用完全不同。

第一个代码接受匿名委托,并对所有不同的项并行地在此代码上运行多个线程。

第二个在这种情况下不太有用。简而言之,它的目的是对多个线程执行查询,并组合结果,然后再将其交给调用线程。所以 foreach 语句上的代码始终保留在 UI 线程上。

只有在 AsParallel()调用右侧的 linq 查询中执行某些代价高昂的操作时,才有意义,比如:

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

区别在于 B 不是平行的。AsParallel()所做的唯一一件事情就是它包装了一个 IEnumerable,这样当您使用 LINQ 方法时,就可以使用它们的并行变体。包装器的 GetEnumerator()(在 foreach的幕后使用)甚至返回原始集合的 GetEnumerator()的结果。

顺便说一句,如果你想查看反射器中的方法,AsParallel()System.Core程序集中的 System.Linq.ParallelEnumerable类中。Parallel.ForEach()mscorlib程序集(命名空间 System.Threading.Tasks)中。

第二个方法将不是并行的,在您的示例中使用 As盲()的正确方法是

IEnumerable<string> items = ...


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