22

複数のアイテムを保持でき、複数のターゲット ブロックにリンクできるが、フィルター/述語を渡す特定のターゲット ブロックにのみアイテムを転送できる TPL データ フロー ブロック ソリューションを探しています。アイテムが同時に複数のターゲット ブロックに配信されることはありません。常に、フィルターに一致するブロックにのみ配信されるか、アイテムを破棄できます。私は BroadCastBlock が好きではありません。私の理解が正しければ、配信は保証されず (または保証されますか?)、フィルタリングはターゲット ブロック側で行われるため、BroadCastBlock は基本的に各項目のコピーをすべての linkedTo ターゲット ブロックに送信します。また、私の理解が正しければ、いつでも複数のアイテムを保持することはありません。Post/Async を使用したくありませんが、LinkTo チェーンを維持します。

完全なカスタム データ フロー ブロックを回避する方法はありますか? または、BroadCastBlock の仕組みを誤解していますか? 残念ながら、詳細を説明し、ユースケースをカバーするドキュメントはあまりありません。どんなアイデアでも大歓迎です。

4

2 に答える 2

35

私があなたを正しく理解していれば、あなたが望むことはBufferBlock、述語ですべてのターゲットブロックにリンクされる単純なによって達成される可能性があります。また、(無条件に)NullTargetブロックにリンクして、一致しなかったアイテムを破棄します。

何かのようなもの:

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

このようにして、各アイテムは、一致する最初のターゲット(存在する場合)に送信されます。

BroadcastBlock各アイテムを複数のターゲットに送信する場合、またはターゲットブロックの速度が十分でない場合にアイテムを破棄する場合に便利です。

を使用BroadcastBlockすると、ブロックがアイテムを受け入れない場合(後で受け入れることができる場合でも)、アイテムがドロップされる可能性があります。ただし、アイテムがランダムにドロップされるわけではないため、ターゲットブロックがBoundedCapacity設定されていない場合は、拒否されないすべてのアイテムを確実に取得できると思います(たとえば、で述語を使用することによりLinkTo())。

于 2012-11-28T16:10:54.790 に答える
11

受け入れられた答えが間違っていることがわかりました。NullTarget は、消費者の否定である述語にリンクする必要があります。そうしないと、消費したいメッセージをドロップする可能性があります。

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));
于 2015-06-19T19:55:05.890 に答える