Parallel.ForEach 与 Task.Factory.StartNew [英] Parallel.ForEach vs Task.Factory.StartNew

查看:23
本文介绍了Parallel.ForEach 与 Task.Factory.StartNew的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

What is the difference between the below code snippets? Won't both be using threadpool threads?

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

For instance if I want to call a function for each item in a collection,

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

vs

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

推荐答案

第一个是更好的选择.

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

Parallel.ForEach, internally, uses a Partitioner<T> to distribute your collection into work items. It will not do one task per item, but rather batch this to lower the overhead involved.

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

The second option will schedule a single Task per item in your collection. While the results will be (nearly) the same, this will introduce far more overhead than necessary, especially for large collections, and cause the overall runtimes to be slower.

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

FYI - The Partitioner used can be controlled by using the appropriate overloads to Parallel.ForEach, if so desired. For details, see Custom Partitioners on MSDN.

在运行时的主要区别是第二个将异步执行.这可以使用 Parallel.ForEach 复制:

The main difference, at runtime, is the second will act asynchronous. This can be duplicated using Parallel.ForEach by doing:

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

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

By doing this, you still take advantage of the partitioners, but don't block until the operation is complete.

这篇关于Parallel.ForEach 与 Task.Factory.StartNew的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆