【问题标题】:TPL DataFlow vs BlockingCollectionTPL 数据流与 BlockingCollection
【发布时间】:2014-01-16 13:44:05
【问题描述】:

我知道BlockingCollection 最适合消费者/生产者模式。但是,何时使用 TPL DataFlow 库中的 ActionBlock

我最初的理解是对于 IO 操作,保留 BlockingCollection,而 CPU 密集型操作最适合 ActionBlock。但我觉得这不是故事的全部……还有其他见解吗?

【问题讨论】:

  • BlockingCollection 对 I/O 来说并不好——实际上由于不支持异步而更糟。

标签: .net task-parallel-library data-synchronization tpl-dataflow


【解决方案1】:

TPL 数据流更适合基于角色的设计。这意味着,如果您想链接生产者和消费者,使用 TDF 会容易得多。

TPL 数据流的另一大优点是它在构建时考虑了async。您可以以同步方式async 方式生产和消费(两者同时),这非常有用。 (我主要以同步方式生产并以非阻塞async 方式消费)。

您还可以非常轻松地设置有限容量和并行度。

TL;DR:BlockingCollection 是一个简单而通用的工具。 TPL Dataflow 更加健壮,但对于特定问题来说可能是矫枉过正或不合适。

【讨论】:

  • @i3amon 你能给出指导或例子吗? TPL 数据流怎么可能是矫枉过正和不合适的呢?即使在简单的情况下,稳健性也不会受到伤害。有性能问题吗?谢谢。
  • @silvalli TPL Dataflow 让您以某种方式操作,BlockingCollection 可以随心所欲地进行。 BlockingCollection 的问题在于它只是同步的。但是现在你有 System.Threading.Channels 库来避免这种情况。所以这取决于你想要结构化还是非结构化并发。
  • @silvalli 我现在几乎在所有情况下都会避免使用 BlockingCollection。
  • @i3amon 我们可以使用数据流来处理一个多线程的 sqs 队列,主要是 IO 操作
  • @pankysharma 这取决于你如何使用它.. 但可以肯定。 SQS 队列消息在处理时需要显式删除,因此您需要在整个数据流中传递该上下文并在完成后删除。
【解决方案2】:

不确定重复使用 Block 一词是否会引起混淆。它们是非常不同的东西。

你说得对,BlockingCollection 非常适合生产者消费者的情况,因为它会阻止读取它的尝试,直到数据可用。但是,BlockingCollection 不是 TPL 数据流的一部分。它是在 .NET 4.0 中作为一种新的线程安全集合类型引入的。

然而,ActionBlock 是一种由 TPL Dataflow 定义的“块”类型,可用于执行操作。 Block,在这个意义上,更多是指它作为数据流的一部分使用。

TPL 中定义的数据流由块组成,主要分为三种类型。来自文档:

TPL 数据流库由数据流块组成,这些块是缓冲和处理数据的数据结构。 TPL 定义了三种数据流块:源块、目标块和传播器块。源块充当数据源并且可以从中读取。目标块充当数据的接收者并且可以被写入。传播器块既充当源块又充当目标块,并且可以读取和写入。 TPL 定义了 System.Threading.Tasks.Dataflow.ISourceBlock 接口来表示源,System.Threading.Tasks.Dataflow.ITargetBlock 来表示目标,System.Threading.Tasks.Dataflow.IPropagatorBlock 来表示传播者。 IPropagatorBlock 继承自 ISourceBlock 和 TargetBlock。 TPL 数据流库提供了几种实现 ISourceBlock、ITargetBlock 和 IPropagatorBlock 接口的预定义数据流块类型。这些数据流块类型在本文档的预定义数据流块类型部分中进行了描述。

ActionBlock 是 ITargetBlock 的一种,它接受输入,执行操作,然后停止。

要回答您的第一个问题,我认为您可以在流程简单时使用 BlockingCollection。当您的流程更复杂时,您会使用 TPL 数据流,在这种情况下,您可能不需要 BlockingCollection。

这里有使用 BlockingCollection 的生产者-消费者问题示例: http://blogs.msdn.com/b/csharpfaq/archive/2010/08/12/blocking-collection-and-the-producer-consumer-problem.aspx?Redirected=true 和这里: http://programmerfindings.blogspot.co.uk/2012/07/producer-consumer-problem-using-tpl-and.html

这些都不使用 Dataflow。这里有一个使用 Dataflow 的示例:

http://msdn.microsoft.com/en-us/library/hh228601(v=vs.110).aspx

另外,我强烈建议您在此处阅读 TPL 数据流文档:

http://msdn.microsoft.com/en-us/library/hh228601(v=vs.110).aspx

如果你正在实现任何复杂的东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-30
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多