TPL数据流,是否有#34; WaitAny"?

时间:2017-03-03 09:44:48

标签: c# task-parallel-library tpl-dataflow

如果我说得对,JoinBlock<T1, T2>就是&#34; WaitAll&#34; TPL数据流:当你有一个T1和一个T2时,它构建一个Tuple<T1, T2>并将其传递给下一个块。

是否有&#34; ChoiceBlock<T1, T2>&#34;,&#34; WaitAny&#34; Dataflow,其中Block<T1>Block<T2>下一步执行?

类似的东西:

var choice = new ChoiceBlock<string, int>
res1.LinkTo(choice.Target1);
res2.LinkTo(choice.Target2);

choice.LinkTo(intConsumer);
choice.LinkTo(stringConsumer);

编辑:this answer几乎就是我想要的,我想知道当你有不同类型的消费者时,是否有原生/更优雅的解决方案,并避免所有的铸造和类型( T)检查。

EDIT2:只是为了让它更清晰:这是有效的

            var stringCast = new TransformBlock<object,string>(o => (string)o);
            var stringTarget = new ActionBlock<string>(m_printAction);
            stringCast.LinkTo(stringTarget);

            var eventCast = new TransformBlock<object, Event>(o => (Event)o);
            var eventTarget = new ActionBlock<Event>(m_addEventAction);
            eventCast.LinkTo(eventTarget);

            var forwarder = new BufferBlock<object>();
            forwarder.LinkTo(stringCast, item => item is string);
            forwarder.LinkTo(eventCast, item => item is Event);

            forwarder.LinkTo(DataflowBlock.NullTarget<object>());

            m_messages.LinkTo(forwarder);
            m_events.LinkTo(forwarder);

但它丑陋且效率低下。有更合适的东西吗?

旧的CCR(并发和协调运行时)曾经同时具有Join和Choice,但我无法在TPL Dataflow中找到Choice。我错过了什么吗?

1 个答案:

答案 0 :(得分:4)

除了使用Dataflowblock.Choose MSDN创意之外。

在您的示例中确实没有做出任何选择:

var choice = new ChoiceBlock<string, int>
res1.LinkTo(choice.Target1);
res2.LinkTo(choice.Target2);

choice.LinkTo(intConsumer);
choice.LinkTo(stringConsumer);

前面的块必须知道它将输出什么类型,导致丑陋的对象类型参数,或者你将不必要地将两个块链接成一个。假设后者对两个不同类型的管道有什么不对?

var buffer1 = new BufferBlock<int>();
var buffer2 = new BufferBlock<string>();
var transform1 = new TransformBlock<int, int>((x) => x);
var transform2 = new TransformBlock<string, string>((x) => x);
buffer1.LinkTo(transform1);
buffer2.LinkTo(transform2);
  

是否有&#34; ChoiceBlock&#34;,&#34; WaitAny&#34; Dataflow,其中Block<T1>Block<T2>下一步执行?

在任何时候,如果输出在任何一个源(即缓冲区)都可用,则它可用于Block<int>Block<string>。这是不是以打字方式填写了WaitAny隐含合约?

不一定是对OP问题的回答,但对于评论来说太长了。