Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
450 views
in Technique[技术] by (71.8m points)

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

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 item to only a specific target block that passes a filter/predicate. At no time should an item be delivered to multiple target blocks at the same time, always only to the one which matches the filter or the item can be discarded. I am not fond of BroadCastBlock because, if I understand correctly, it does not guarantee delivery (or does it?) and the filtering is done on the target block side, meaning BroadCastBlock essentially sends copies of each item to all linkedTo target blocks. It also does not hold more than one item at any time if I understand correctly. I do not want to use Post/Async but maintain a LinkTo chain.

Is there a way around a complete custom data flow block? Or am I misunderstanding how BroadCastBlock works? Unfortunately there really is not much documentation out there that goes into detail and covers use cases. Any ideas are highly appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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()).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...