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




.net multithreading parallel-processing (4)

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

IEnumerable<string> items = ...

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

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

A:

IEnumerable<string> items = ...

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

B:

IEnumerable<string> items = ...

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

使用另一个有不同的后果吗? (假设我在两个例子的括号内都是线程安全的。)


不同的是,B不平行。 AsParallel()所做的唯一事情就是将它包装在一个IEnumerable ,以便在使用LINQ方法时使用它们的并行变体。 包装器的GetEnumerator() (它在foreach后面使用)甚至返回原始集合的GetEnumerator()

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


他们做了非常不同的事情。

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

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

它只有在你在AsParallel()调用的右边的linq查询中执行一些昂贵的事情时才有意义,例如:

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

两者都会给你延期执行,是的。

至于哪一个比另一个更受欢迎,这取决于你的底层数据源是什么。

返回一个IEnumerable将自动强制运行时使用LINQ to Objects来查询你的集合。

返回一个IQueryable(顺便实现IEnumerable)提供了额外的功能,可以将您的查询转换为可能在底层源代码(LINQ to SQL,LINQ to XML等)上表现更好的东西。





c# .net multithreading parallel-processing parallel.foreach