Erg,我正在尝试使用Reflector在BCL中找到这两个方法,但找不到它们。这两个片段有什么区别?
A:
IEnumerable<string> items = ...
Parallel.ForEach(items, item => {
...
});
B:
IEnumerable<string> items = ...
foreach (var item in items.AsParallel())
{
...
}
使用一个比另一个有不同的后果吗? (假设我在两个示例的括号内部所做的事情都是线程安全的。)
答案 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
});