Parallel.ForEach 与 Task.Factory.StartNew

问题描述

一个是更好的选择。

Parallel.ForEach 在内部使用 aPartitioner<T>将您的集合分发到工作项中。它不会对每个项目执行一项任务,而是将其批处理以降低所涉及的开销。

Task第二个选项将为您的收藏中的每个项目安排一个。虽然结果将(几乎)相同,但这将引入比必要更多的开销,尤其是对于大型集合,并导致整体运行时变慢。

仅供参考 - 如果需要,可以通过对 Parallel.ForEach 使用适当的重载来控制使用的分区器。有关详细信息,请参阅MSDN 上的自定义分区器。

在运行时,主要区别在于第二个将异步执行。这可以通过执行以下操作使用 Parallel.ForEach 复制:

Task.Factory.StartNew( () => Parallel.ForEach<Item>(items, item => DoSomething(item)));

通过这样做,您仍然可以利用分区器,但在操作完成之前不要阻塞。

解决方法

下面的代码片段有什么区别?两者都不会使用线程池线程吗?

例如,如果我想为集合中的每个项目调用一个函数,

Parallel.ForEach<Item>(items,item => DoSomething(item));

vs

foreach(var item in items)
{
  Task.Factory.StartNew(() => DoSomething(item));
}