TPL DataFlow与BlockingCollection的比较

8
我知道BlockingCollection最适合使用在消费者/生产者模式中。但是,什么时候应该使用TPL DataFlow库中的ActionBlock呢?
我的初步理解是对于IO操作,应该使用BlockingCollection。而对于计算密集型操作,则最好使用ActionBlock。但我感觉这并不是全部内容...你有其他更深入的见解吗?

BlockingCollection 对于 I/O 来说并不是更好的选择,事实上由于不支持异步操作,它反而更差。 - Cory Nelson
2个回答

10
TPL Dataflow更适合基于Actor的设计。这意味着如果您想要链接生产者和消费者,使用TDF会更容易。
另一个TDF的优点是它考虑了async。您可以同步地生产和消费,也可以异步地生产和消费(甚至同时进行),这非常有用。(我通常是同步生产,非阻塞异步消费)。
您还可以非常容易地设置有限容量和并行度。
简而言之:BlockingCollection是一种简单而通用的工具。TPL Dataflow更加健壮,但对于特定问题可能过于复杂或不适用。

@i3amon,你能给一些指导或示例吗?TPL Dataflow 怎么会过度设计和不适用呢?即使在简单情况下,鲁棒性也不会有害。是否存在性能问题?谢谢。 - silvalli
1
@silvalli TPL Dataflow让你按照一定的方式操作,而BlockingCollection则可以根据你的意愿进行操作。BlockingCollection的问题在于它只支持同步。但现在你有了System.Threading.Channels库来避免这个问题。所以这取决于你想要结构化还是非结构化并发。 - i3arnon
1
@silvalli 我现在几乎在所有情况下都会避免使用BlockingCollection。 - i3arnon
@i3amon,我们可以使用数据流来处理一个带有多线程方法的sqs队列,主要是IO操作。 - panky sharma
@pankysharma 这取决于你如何使用它...但当然可以。SQS队列消息在处理时需要显式删除,因此您需要在整个数据流中传递该上下文并在完成后进行删除。 - i3arnon
谢谢,您能在这里回答我的问题吗? https://dev59.com/78Hqa4cB1Zd3GeqP9-qQ?noredirect=1#comment122003482_68961003 - panky sharma

3

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

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

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

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

TPL Dataflow库由数据流块组成,这些块是缓冲和处理数据的数据结构。TPL定义了三种数据流块:源块、目标块和传播块。源块充当数据源,并且可以从中读取。目标块充当数据接收器,并且可以写入。传播块既充当源块又充当目标块,并且可以进行读取和写入操作。TPL定义了System.Threading.Tasks.Dataflow.ISourceBlock接口来表示源,System.Threading.Tasks.Dataflow.ITargetBlock表示目标,System.Threading.Tasks.Dataflow.IPropagatorBlock表示传播器。IPropagatorBlock继承自ISourceBlock和TargetBlock。 TPL Dataflow库提供了几种预定义的数据流块类型,这些类型实现了ISourceBlock、ITargetBlock和IPropagatorBlock接口。这些数据流块类型在本文档的“预定义数据流块类型”部分中描述。
ActionBlock是ITargetBlock的一种类型,它接收输入,执行操作,然后停止。
回答你的第一个问题,我认为当您的进程简单时,可以使用BlockingCollection。当您的进程更复杂时,您将使用TPL Dataflow,在这种情况下,您可能不需要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 Dataflow文档:

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

如果您正在实现任何复杂的内容。

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