TPL 数据流,是否有 "WaitAny" 的块?

TPL Dataflow, is there a block for "WaitAny"?

如果我没记错,JoinBlock<T1, T2> 是 TPL 数据流的 "WaitAll":当你有一个 T1 和一个 T2 时,它会构建一个 Tuple<T1, T2> 并将其传递给下一个阻止。

是否有Dataflow的"WaitAny"“ChoiceBlock<T1, T2>”,接下来执行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 几乎是我想要的,我只想知道当你有不同类型的消费者时是否有 native/more 优雅的解决方案,并避免所有的转换和typeof(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。我错过了什么吗?

除了一些真正创意 Dataflowblock.Choose MSDN.

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

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

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

前面的块必须不知道它要输出什么类型,导致丑陋的对象类型参数,否则你会link不必要地进入两个块一。假设后者,两个不同类型的管道有什么问题?

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);

Is there a "ChoiceBlock", the "WaitAny" of Dataflow, where either a Block<T1> or a Block<T2> are executed next?

在任何时候,如果任一源(即缓冲区)的输出变得可用,则它可用于 Block<int>Block<string>。这不是以类型化的方式完成 WaitAny 隐含合同吗?

不一定是 OP 问题的答案,但评论时间太长。