[英]Multicast block TPL Dataflow
我需要將一個對象多播到多個路徑中
producer
|
multicast
| |
Process1 Process2
| |
Writedb WriteFile
廣播塊沒有多大幫助,它只對進程 1 和進程 2 進行最新的處理,如果進程 2 運行晚了,那么它將無法接收消息。
db writer 和 write file 有不同的數據。
這是以下代碼片段。
class Program
{
public static void Main()
{
var broadCastBlock = new BroadcastBlock<int>(i => i);
var transformBlock1 = new TransformBlock<int, string>(i =>
{
Console.WriteLine("1 transformblock called: {0}", i);
//Thread.Sleep(4);
return string.Format("1_ {0},", i);
});
var transformBlock2 = new TransformBlock<int, string>(i =>
{
Console.WriteLine("2 transformblock called: {0}", i);
Thread.Sleep(100);
return string.Format("2_ {0},", i);
});
var processorBlockT1 = new ActionBlock<string>(i => Console.WriteLine("processBlockT1 {0}", i));
var processorBlockT2 = new ActionBlock<string>(i => Console.WriteLine("processBlockT2 {0}", i));
//Linking
broadCastBlock.LinkTo(transformBlock1, new DataflowLinkOptions { PropagateCompletion = true });
broadCastBlock.LinkTo(transformBlock2, new DataflowLinkOptions { PropagateCompletion = true });
transformBlock1.LinkTo(processorBlockT1, new DataflowLinkOptions { PropagateCompletion = true });
transformBlock2.LinkTo(processorBlockT2, new DataflowLinkOptions { PropagateCompletion = true });
const int numElements = 100;
for (int i = 1; i <= numElements; i++)
{
broadCastBlock.SendAsync(i);
}
//completion handling
broadCastBlock.Completion.ContinueWith(x =>
{
Console.WriteLine("Braodcast block Completed");
transformBlock1.Complete();
transformBlock2.Complete();
Task.WhenAll(transformBlock1.Completion, transformBlock2.Completion).ContinueWith(_ =>
{
processorBlockT1.Complete();
processorBlockT2.Complete();
});
});
transformBlock1.Completion.ContinueWith(x => Console.WriteLine("Transform1 completed"));
transformBlock2.Completion.ContinueWith(x => Console.WriteLine("Transform2 completed"));
processorBlockT1.Completion.ContinueWith(x => Console.WriteLine("processblockT1 completed"));
processorBlockT2.Completion.ContinueWith(x => Console.WriteLine("processblockT2 completed"));
//mark completion
broadCastBlock.Complete();
Task.WhenAll(processorBlockT1.Completion, processorBlockT2.Completion).ContinueWith(_ => Console.WriteLine("completed both tasks")).Wait();
Console.WriteLine("Finished");
Console.ReadLine();
}
}
通過廣播保證交付的最佳方法是什么? 即多播。
我是否應該只在兩端插入兩個緩沖區然后使用它,以便緩沖區始終收集進來的內容,然后該過程可能需要一些時間來處理所有這些內容?
BroadcastBlock
保證所有消息都將提供給所有鏈接塊。 所以這正是您所需要的。 不過,您應該解決的是您向BroadcastBlock
提供消息的方式:
for (int i = 1; i <= numElements; i++)
{
broadCastBlock.SendAsync(i); // Don't do this!
}
應該等待SendAsync
方法。 您永遠不應有多個針對同一塊的掛起SendAsync
操作。 這樣做不僅破壞了對接收消息順序的所有保證,而且內存效率極低。 使用有界塊的全部意義在於通過限制塊的內部緩沖區的大小來控制內存使用。 通過發出多個未等待的SendAsync
命令,您可以通過創建一個不完整的Task
的外部動態緩沖區來規避這種自我施加的限制,每個任務的權重為數百個字節,用於傳播僅具有此權重的一小部分的消息。 通過首先不使塊有界,可以更有效地在內部緩沖這些消息。
for (int i = 1; i <= numElements; i++)
{
await broadCastBlock.SendAsync(i); // Now it's OK
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.