【问题标题】:How can I branch logic in TPL Dataflow?如何在 TPL 数据流中分支逻辑?
【发布时间】:2014-09-02 14:46:43
【问题描述】:

我是 TPL 数据流的新手,如果这是一个简单的问题,请见谅。

我有一个采用基类的输入缓冲区块。如何从那里分支到基于派生类型的块?比如:

var inputBlock = new BufferBlock<EventBase>();
//if EventBase is Meeting then go to block X
//if EventBase is Appointment the go to block Y

谢谢!

【问题讨论】:

  • 你没有。这就是多态性的全部意义所在。您应该让每个派生类型覆盖基类型成员,以便使用基类型成员区分行为。
  • 所以你说没有办法做到这一点?我可以在循环中的 TPL 数据流之外执行它,并且只是 if(EventBase is Meeting){},我要问的是如何在数据流块中完成它?我需要自定义块吗?
  • 我不是告诉你这是不可能的,我是告诉你这是个坏主意。这表明设计不佳。你不应该这样做。相反,您应该通过使用多态性来设计块以支持任何类型的EventBase

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


【解决方案1】:

您可以向LinkTo 方法发送谓词来区分项目。但是,您需要从每个块内的 EventBase 向下转换以使用特定于该类型的逻辑:

var inputBlock = new BufferBlock<EventBase>();
var meetingBlock = new ActionBlock<EventBase>(
    eventBase =>
    {
        var meeting = eventBase as Meeting;
        //...
    });
var appointmentBlock = new ActionBlock<EventBase>(
    eventBase =>
    {
        var appointment = eventBase as Appointment;
        //...
    });

inputBlock.LinkTo(meetingBlock, eventBase => eventBase is Meeting);
inputBlock.LinkTo(appointmentBlock, eventBase => eventBase is Appointment);

但正如 Servy 指出的那样,您可能应该避免这种情况,并设计您的类型以支持多态性。

【讨论】:

  • 谢谢,这看起来像我所追求的。而且我理解你们所说的糟糕的设计,不幸的是,我受上游提供商的摆布,他们的 xml 块设计得有些糟糕,所以为了缓解我的反序列化问题,一个 xml 数组 有会议和约会节点最容易用基类反序列化并以这种方式分支逻辑进行处理。很可能会有更好的设计,但在这一点上,我已经走了很长一段路,不想回到反序列化代码。
【解决方案2】:

如果您想要一个更简单的解决方案并且不介意使用基于 TPL 数据流构建的帮助程序库,DataflowEx 提供了一个 LinkSubTypeTo() 方法。

Dataflow<TIn, TOut> flow1;
Dataflow<TOutSubType1> flow2;
Dataflow<TOutSubType2> flow3;

flow1.LinkSubTypeTo(flow2);
flow1.LinkSubTypeTo(flow3);

请查看图书馆文档的advanced linking 部分。在内部,它使用@I3arnon 引入的相同机制。

免责声明:我是DataflowEx的作者。

【讨论】:

    猜你喜欢
    • 2011-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-30
    相关资源
    最近更新 更多