How can I branch logic in TPL Dataflow?
Asked Answered
T

2

7

Im brand new to TPL dataflow so forgive me if this is a simple question.

I have an input buffer block that takes a base class. How can I branch from there to a block based on the derived type? So for example:

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

Thanks!

Tiphanie answered 2/9, 2014 at 14:46 Comment(3)
You don't. That's the whole point of polymorphism. You should have each derived type override base type members in such a way as to differentiate the behavior using base type members.Damsel
So your telling there is no way to do this? I can do it outside of TPL dataflow in a loop and just if(EventBase is Meeting){}, what I'm asking is how is this done in dataflow blocks? Do I need a custom block?Tiphanie
I'm not telling you it's impossible, I'm telling you that it's a bad idea. It's indicative of bad design. You shouldn't do this. Instead you should design the blocks to support any type of EventBase, through the use of polymorphism.Damsel
H
8

You can send a predicate to the LinkTo method to distinguish between the items. You would however need to downcast from EventBase inside each block to use logic specific to that type:

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

But as Servy pointed out you should probably avoid that and design your types to support polymorphism.

Hendrix answered 2/9, 2014 at 15:59 Comment(1)
Thanks, this looks like what Im after. And I understand what you guys are saying about it being bad design, unfortunately Im at the mercy of the upstream provider and their xml chunks are somewhat poorly designed so to alleviate my deserialization issues an xml array of <events> which has meeting and appointment nodes was easiest to deserialize with the base class and branch the logic this way to process. There very well may be a better design but at this point Im pretty far along and dont want to go back to the deserialization code.Tiphanie
F
1

If you want a simpler solution and don't mind using a helper library built upon TPL Dataflow, there is DataflowEx which provides a LinkSubTypeTo() method.

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

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

Please check the advanced linking section of the library's document. Internally it uses the same mechanism @I3arnon introduced.

Disclaimer: I am the author of DataflowEx.

Fushih answered 20/12, 2014 at 13:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.