我需要将一个对象多播到多个路径
producer
|
multicast
| |
Process1 Process2
| |
Writedb WriteFile
广播块没有多大帮助,它只对PROCESS1进程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();
}
}
通过广播保证投放的最佳方法是什么?即多播。
我应该只在两端插入两个缓冲区,然后使用它,以便缓冲区始终收集正在进行的内容,然后该过程可能需要一些时间来处理所有这些缓冲区?
答案 0 :(得分:0)
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
}