阻塞集合(BlockingCollection)和任务调度器(TaskScheduler)之间的区别。

3
我曾通过使用Parallel.ForEach来并行处理我的项目,那时候效果还不错。但是主要开发人员出现了,他表示不喜欢这种方法并希望我改变。
之后,我决定使用TaskScheduler和TaskFactory来批量处理工作,结果非常完美快速,但他仍然认为这种做法过于繁琐老旧,建议我采用BlockingCollection与消费者/生产者模式。他开始实施这个方案,但我并不认为它比TaskScheduler更有优势,也许只是为了避免维护问题或保持适度的复杂性,我不知道。
在这里提供一些背景信息,这项工作是将数据从内存中转换,这些数据不需要同步上下文,每个操作都可以单独进行,没有IO限制,并且所有代码都是线程安全的。
那么,BlockingCollection和TaskScheduler在并行处理方面有什么区别呢?

1
也许你的工作是IO bound和异步的,这意味着Parallel.ForEach不太适合。无论如何,你需要更多的信息,因为当前状态下这个问题很难回答。 - TheGeneral
顺便提一下,Parallel.ForEach 已经实现了发布/订阅模式。发布者是输入的可枚举对象,订阅者则是工作线程。它非常适用于数据并行处理,但不支持异步和并发操作。并行处理 ≠ 异步 ≠ 并发。 - Panagiotis Kanavos
1
@Maillful,没有信息怎么能说呢?他在运行时无法知道其背后的行为。他可以阅读源代码,因为它是开源的。或者他可以阅读文档-数据并行性并行编程模式:理解和应用.NET Framework 4中的并行模式 - Panagiotis Kanavos
1
还有LINQ和TPL的自定义分区器。该文章解释了分割类型(静态vs动态)、它们固有的批处理和负载均衡行为、如何创建必要的自定义分区器,以及如何配置内置分区器。 - Panagiotis Kanavos
1
还有Amdahl's Law - 最佳性能增益取决于不能并行化的工作部分。这就解释了为什么BlockingCollection或任何类型的同步都是不好的。 - Panagiotis Kanavos
显示剩余12条评论
1个回答

1
所以,阻塞集合(BlockingCollection)和任务调度器(TaskScheduler)在并行工作方面有什么区别呢?
正如评论中所说的那样,它们就像黑夜和橙子一样不同。 BlockingCollection是您在命名空间System.Collections.Concurrent中找到的集合。它基本上由来自System.Collections.Generic的所有内容组成,它们可以通过在每个合理的位置使用lock语句完全保护免受竞争条件的影响。
如果您想要一个集合位于外部,则无法从内部完全证明该集合不会发生竞争条件。只有使用这些集合的代码才能避免竞争条件(这也是为什么数组和List没有并发对应项的原因)。
他并不是真的喜欢这个,再次他不喜欢它并认为它过度,他说我应该使用带有消费者/生产者模式的BlockingCollection。
那么,无论如何,区别都不重要。选择不在您手中。

你可能还不知道其他地方的要求。或者“老狗学不会新把戏”也许适用。


那更像是“非我所造”(Not Invented Here)。TPL 已经有 10 年历史了。 - Panagiotis Kanavos
@PanagiotisKanavos 如果狗已经超过20岁了,那就不算太多了。^^ 另外选项A仍然存在。如果这只狗已经>10岁了,我不敢想象代码有多老了。 - Christopher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接