TPL Dataflow, how to forward items to only one specific target block among many linked target blocks?

后端 未结 2 726
粉色の甜心
粉色の甜心 2020-12-17 09:40

I am looking for a TPL data flow block solution which can hold more than a single item, which can link to multiple target blocks, but which has the ability to forward an ite

相关标签:
2条回答
  • 2020-12-17 09:54

    I've found the accepted answer to be incorrect. The NullTarget should be linked with its predicate being the negation of your consumers. Otherwise you might drop messages that you wanted to consume.

    var forwarder = new BufferBlock<SomeType>();
    forwarder.LinkTo(target1, item => matchesTarget1(item));
    forwarder.LinkTo(target2, item => matchesTarget2(item));
    forwarder.LinkTo(DataflowBlock.NullTarget<SomeType>(), item => !matchesTarget1(item) && !matchesTarget2(item));
    
    0 讨论(0)
  • 2020-12-17 10:02

    If I understand you correctly, what you want could be accomplished by a simple BufferBlock, which would be linked to all your target blocks with predicates. You would also (unconditionally) link it to a NullTarget block, to discard items that didn't match.

    Something like:

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

    This way, each item will be sent to the first target that matches, if there is any.

    BroadcastBlock can be useful if you want to send each item to multiple targets, or if you want to discard items if the target block is not fast enough.

    With BroadcastBlock, items may be dropped if no block accepts them (even though they may be able to accept it later). But it doesn't drop items at random, so if your target blocks don't have BoundedCapacity set, I think you can be sure that they will get all items that they don't decline (e.g. by using predicate in LinkTo()).

    0 讨论(0)
提交回复
热议问题