ActionBlockに直接ポストするのではなく、(BoundedCapacityを使用して)スロットリング以外のActionBlockにリンクされたBufferBlockを使用する利点があるかどうかは疑問でした。スロットリングが必要ない限り長い間)。データフローネットワークでBufferBlock <T>を使用するメリット
答えて
1ブロックから複数のアイテムにアイテムを転送するだけの場合は、BufferBlock
は必要ありません。
しかし、確かに有用な場合があります。たとえば、複雑なデータフローネットワークを使用している場合、独自の方法で作成されたより小さなサブネットワークから構築することができます。これを行うには、ブロックのグループを表現するための方法が必要です。あなたが言及したケースでは、その単一のBufferBlock
(おそらくITargetBlock
)を返すのは簡単な解決策になります。
BufferBlock
が便利なもう1つの例は、複数のソースブロックから複数のターゲットブロックにアイテムを送信する場合です。 BufferBlock
を仲介者として使用した場合、各ソースブロックを各ターゲットブロックに接続する必要はありません。
BufferBlock
を使用できる他の多くの例があります。もちろん、あなたのケースでそれを使用する理由がない場合は、しないでください。
svickの答えに追加するには、バッファブロックの別の利点があります。複数の出力リンクを持つブロックがあり、それらの間のバランスを取る必要がある場合は、出力ブロックを貪欲でないものにし、キューブロックを処理するバッファブロックを追加する必要があります。
- いくつかのコードブロックは、それはだ使用BufferBlockにデータを掲載します:
これは、我々が行うことを計画しているものです。今死んでいるリンクより引用
:私は便利な次の例を見つけましたポスト(T t)法。
- このBufferBlockは、BufferBlockのLinkTo t)メソッドを使用して3つのActionBlockインスタンスにリンクされています。
BufferBlockは、入力データのコピーをリンク先のすべてのターゲットブロックに渡すことはありません。その代わりに、1つのターゲットブロックのみに処理されます。ここでは、1つのターゲットが他のターゲットに引き渡されます。
- アクションA1が1
- アクションA1が値2
- アクションA1が実行して実行値で実行:それは次の出力を生成し、実行すると
static void Main(string[] args) { BufferBlock<int> bb = new BufferBlock<int>(); ActionBlock<int> a1 = new ActionBlock<int>((a) => { Thread.Sleep(100); Console.WriteLine("Action A1 executing with value {0}", a); } ); ActionBlock<int> a2 = new ActionBlock<int>((a) => { Thread.Sleep(50); Console.WriteLine("Action A2 executing with value {0}", a); } ); ActionBlock<int> a3 = new ActionBlock<int>((a) => { Thread.Sleep(50); Console.WriteLine("Action A3 executing with value {0}", a); } ); bb.LinkTo(a1); bb.LinkTo(a2); bb.LinkTo(a3); Task t = new Task(() => { int i = 0; while (i < 10) { Thread.Sleep(50); i++; bb.Post(i); } } ); t.Start(); Console.Read(); }
:それでは、以下のコードを参照してみましょう値3を持つ
- 値1で実行するアクションA1
- 値5で実行するアクションA1
- 値10
これは、(Thread.Sleep(100)が意図的に追加されたため)ビジー状態であっても実際にすべてのデータを実行しているターゲットが1つだけであることを示しています。
これは、すべてのターゲットブロックがデフォルトで貪欲であり、データを処理できない場合でも入力をバッファリングするためです。この動作を変更するには、DataFlowBlockOptionsでGreedyプロパティをfalseに設定しました。次のようにActionBlockを実行します。
static void Main(string[] args)
{
BufferBlock<int> bb = new BufferBlock<int>();
ActionBlock<int> a1 = new ActionBlock<int>((a) =>
{
Thread.Sleep(100);
Console.WriteLine("Action A1 executing with value {0}", a);
}
, new DataflowBlockOptions(taskScheduler: TaskScheduler.Default,
maxDegreeOfParallelism: 1, maxMessagesPerTask: 1,
cancellationToken: CancellationToken.None,
//Not Greedy
greedy: false)
);
ActionBlock<int> a2 = new ActionBlock<int>((a) =>
{
Thread.Sleep(50);
Console.WriteLine("Action A2 executing with value {0}", a);
}
, new DataflowBlockOptions(taskScheduler: TaskScheduler.Default,
maxDegreeOfParallelism: 1, maxMessagesPerTask: -1,
cancellationToken: CancellationToken.None,
greedy: false)
);
ActionBlock<int> a3 = new ActionBlock<int>((a) =>
{
Thread.Sleep(50);
Console.WriteLine("Action A3 executing with value {0}", a);
}
, new DataflowBlockOptions(taskScheduler: TaskScheduler.Default,
maxDegreeOfParallelism: 1, maxMessagesPerTask: -1,
cancellationToken: CancellationToken.None,
greedy: false)
);
bb.LinkTo(a1);
bb.LinkTo(a2);
bb.LinkTo(a3);
Task t = new Task(() =>
{
int i = 0;
while (i < 10)
{
Thread.Sleep(50);
i++;
bb.Post(i);
}
}
);
t.Start();
Console.Read();
}
このプログラムの出力は次のとおり
- アクションA1が値1
- 値2
- アクションA3の実行と実行値3
- アクションA1で実行するアクションA2で実行値6を持つ
- 値7で実行されるアクションA3
- アクションA3の値と実行8
- アクションA2が値5
- アクションA3の値と実行9
- アクションA1 4
- アクションA2値と実行値と実行10
これを用いて実行期待どおり3つのActionBlock(s)の間でデータの分布を明確に示しています。
2番目のコンパイル例を取得できませんでした。 – Nathan
いいえ、いくつかの理由で2番目の例はコンパイルされません。実行ブロックではなく、「グループ化」データフローブロックに対してのみgreedy = falseを設定できます。 GroupingDataflowBlockOptions(DataflowBlockOptionsではなく)で設定する必要があります。コンストラクタパラメータではなくプロパティ値 "{Greedy = false}"に設定されます。
アクションブロックの容量を絞るには、DataflowBlockOptionsのBoundedCapacityプロパティの値を設定します(OPが示すとおり、このオプションはすでに認識されていますが)。このように:
var a1 = new ActionBlock<int>(
i => doSomeWork(i),
new ExecutionDataflowBlockOptions {BoundedCapacity = 1}
);
- 1. EventHandlerを使用するメリット
- 2. arrays.xmlを使用するメリット
- 3. バックエンドでphpを使用するメリット
- 4. CassandraでSparkを使用するメリット
- 5. Rhinoを使用するメリット(mozilla's rhino)
- 6. socketioハートビートを使用するメリット/デメリット
- 7. 複数のエンティティを使用するメリット
- 8. ASP.NET MVCコントローラインジェクションを使用するメリット
- 9. Core Graphicsを使用するメリット
- 10. <?php、<?を使用する際のメリットとデメリット、<script language = "php">、<%in php
- 11. Kerberos TGTの動作
- 12. out/refとreturnを使用するメリットは何ですか?
- 13. OpenIDを使用するメリットとデメリットは何ですか?
- 14. PhonegapとTitaniumを使用するメリットとデメリットは何ですか?
- 15. Protocol vs Inheritanceを使用するメリットとデメリットは何ですか?
- 16. セレンに "xpath"を使用するメリットとデメリットは何ですか?
- 17. tomcatのメリットとメリット<Host>要素の
- 18. PHPを使用してSQLを使用するメリットはどこですか?
- 19. SSH /その他のアプリケーション用にJavaで取得したTGTの使用
- 20. 割り込みコンテキストでmutexを使用することのメリット
- 21. IPCでSocketを使用するメリットとデメリット
- 22. Androidのリモートプロセスでサービスを使用するメリット
- 23. oledbデータプロバイダでsqlclientデータプロバイダを使用するメリット
- 24. GuidesでCompariesChainをObjects.equal()&& Objects.equal()...に使用するメリットは
- 25. スタックを使用するメリットと二重リンクリストを比較する
- 26. サードパーティのソケットを使用することによるJavaのメリット
- 27. Cassandraにヘーゼルキャストを使用するメリットはありますか
- 28. Arrays.asList()を使用してリストを作成するメリット
- 29. Doctrineでは、SQL上でDQLを使用するメリットは何ですか?
- 30. Foundationの「ZURBテンプレート」をCLIから使用するメリット
私はBufferBlocksを使用して、データフローブロック間の通信の「クリーン」な方法ですが、それだけの価値BufferBlocksを使用してのオーバーヘッド(もしあれば)であることを感じていますか? – Dimitri
これはあなたが決定するためのものです。コードがきれいになっていると感じたら、それをしてください。いくつかのオーバーヘッドがありますが、パフォーマンスを本当に気にしない限り、気にならないはずです。 – svick