TPL Dataflow,如何将项目转发到许多链接目标块中的一个特定目标块?

时间:2012-11-28 06:35:30

标签: c# task-parallel-library actor message-passing tpl-dataflow

我正在寻找一个TPL数据流块解决方案,它可以容纳多个项目,可以链接到多个目标块,但是它能够将项目转发到仅通过过滤器的特定目标块/谓语。任何时候都不应该将项目同时传递给多个目标块,始终只能传递给与过滤器匹配的项目,或者可以丢弃该项目。我不喜欢BroadCastBlock,因为如果我理解正确,它不能保证传送(或者是吗?)并且过滤是在目标块侧完成的,这意味着BroadCastBlock基本上将每个项目的副本发送到所有linkedTo目标块。如果我理解正确,它也不会在任何时候持有多个项目。我不想使用Post / Async但维护LinkTo链。

是否有办法绕过完整的自定义数据流程块?或者我误解了BroadCastBlock的工作原理?不幸的是,实际上没有太多文档可以详细介绍并涵盖用例。任何想法都受到高度赞赏。

2 个答案:

答案 0 :(得分:27)

如果我理解正确,您可以通过简单的BufferBlock来完成您想要的事情,该事件将链接到带谓词的所有目标块。您还可以(无条件地)将其链接到NullTarget block,以丢弃不匹配的项目。

类似的东西:

var forwarder = new BufferBlock<SomeType>();
forwarder.LinkTo(target1, item => matchesTarget1(item));
forwarder.LinkTo(target2, item => matchesTarget2(item));
forwarder.LinkTo(DataflowBlock.NullTarget<SomeType>());

这样,每个项目都会被发送到第一个匹配的目标,如果有的话。

如果您想将每个项目发送到多个目标,或者如果您想要在目标块不够快的情况下丢弃项目,

BroadcastBlock会很有用。

使用BroadcastBlock,如果没有块接受它们,则可以删除项目(即使它们稍后可以接受它)。但它不会随意丢弃项目,所以如果您的目标区块没有设置BoundedCapacity,我认为您可以确定他们会获得他们不会拒绝的所有项目(例如,在LinkTo()中使用谓词)。

答案 1 :(得分:7)

我发现接受的答案是不正确的。 NullTarget应该与其谓词相关联,这是对消费者的否定。否则,您可能会丢弃要使用的消息。

$(window).load(function() {

   $('#button1').click(function(){
       $('#om-fantasylab').animatescroll();
   });

   .. same with rest of your buttons ..

});