これが可能かどうかはわかりませんが、可能であれば、おそらく正しく行っていません。多くのコンシューマー (ActionBlocks) にリンクされている 1 つの共有バッファーがあるとします。各コンシューマは、データをバッファにリンクするために使用される述語を満たすデータを消費する必要があります。たとえば、ActionBlock1 は を満たす数値を消費するx => x % 5 == 0
必要があり、ActionBlock2 は のみを消費する必要がありますx => x % 5 == 1
。
これが私が持っているものです:
private static ITargetBlock<int> BuildPipeline(int NumProductionLines)
{
var productionQueue = new BufferBlock<int>();
for (int i = 0; i < NumProductionLines; i++)
{
ActionBlock<int> productionLine = new ActionBlock<int>(num => Console.WriteLine("Processed by line {0}: {1}", i + 1, num));
productionQueue.LinkTo(productionLine, x => x % NumProductionLines == i);
}
return productionQueue;
}
そして、私は電話します:
Random rnd = new Random();
ITargetBlock<int> temp = BuildPipeline(5);
while (true)
{
temp.Post(rnd.Next(255));
}
ただし、これは機能しません。コンソールに出力は表示されません。メソッドを次のように変更した場合BuildPipeline
:
private static ITargetBlock<int> BuildPipeline(int NumProductionLines)
{
var productionQueue = new BufferBlock<int>();
ActionBlock<int> productionLine1 = new ActionBlock<int>(num => Console.WriteLine("Processed by line {0}: {1}", 1, num));
ActionBlock<int> productionLine2 = new ActionBlock<int>(num => Console.WriteLine("Processed by line {0}: {1}", 2, num));
ActionBlock<int> productionLine3 = new ActionBlock<int>(num => Console.WriteLine("Processed by line {0}: {1}", 3, num));
ActionBlock<int> productionLine4 = new ActionBlock<int>(num => Console.WriteLine("Processed by line {0}: {1}", 4, num));
ActionBlock<int> productionLine5 = new ActionBlock<int>(num => Console.WriteLine("Processed by line {0}: {1}", 5, num));
productionQueue.LinkTo(productionLine1, x => x % 5 == 0);
productionQueue.LinkTo(productionLine2, x => x % 5 == 1);
productionQueue.LinkTo(productionLine3, x => x % 5 == 2);
productionQueue.LinkTo(productionLine4, x => x % 5 == 3);
productionQueue.LinkTo(productionLine5, x => x % 5 == 4);
return productionQueue;
}
コードは期待どおりに動作します。
アクションブロックの動的な作成とリンクが機能しない理由を誰かが明らかにすることはできますか?
ITargetBlock<int> temp = BuildPipeline(5);
PS tempの直後にコードに侵入すると、5 つのターゲットがバッファにリンクされていることが示されます。また、各ターゲットの ID は異なります。
前もって感謝します
編集: svick によって提案された変更を追加しましたが、まだ良くありません:
private static ITargetBlock<int> BuildPipeline(int NumProductionLines)
{
var productionQueue = new BufferBlock<int>();
var opt = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 1 };
for (int i = 0; i < NumProductionLines; i++)
{
ActionBlock<int> productionLine = new ActionBlock<int>(num => Console.WriteLine("Processed by line {0}: {1}", i + 1, num));
int j = i;
productionQueue.LinkTo(productionLine, x => x % NumProductionLines == j);
}
ActionBlock<int> discardedLine = new ActionBlock<int>(num => Console.WriteLine("Discarded: {0}", num));
productionQueue.LinkTo(discardedLine);
return productionQueue;
}
現在、2 番目の生産ラインのみがデータを処理します (x % 5 == 1 述語を満たすもの)。データは述語を満たしていません。つまり、9 と 7 で終わる数字が得られます。
編集: 作業コードは次のようになります。
private static ITargetBlock<int> BuildPipeline(int NumProductionLines)
{
var productionQueue = new BufferBlock<int>();
var opt = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 1 };
for (int i = 0; i < NumProductionLines; i++)
{
int j = i;
ActionBlock<int> productionLine = new ActionBlock<int>(num => Console.WriteLine("Processed by line {0}: {1}", j + 1, num));
productionQueue.LinkTo(productionLine, x => x % NumProductionLines == j);
}
productionQueue.LinkTo(DataflowBlock.NullTarget<int>());
return productionQueue;
}