我经常使用TPL并拥有大量的数据流管道结构
作为管道网络的一部分,我想将一些数据写入azure blob存储。我们有大量数据,因此我们有4
个存储帐户,我们希望在它们之间均匀分配数据。
想要继续使用数据流管道模式,因此我想实现一个SourceBlock
,如果我将它链接到几个目标块,它将通过循环将消息发送给它们。 BufferBlock
不够好,因为他将消息发送到接受它的第一个块,并假设所有目标块都具有大的有界容量 - 所有消息将转到第一个目标块。 BroadcastBlock
也不好,因为我不想要重复。
有什么建议吗?使用循环行为实现ISourceBlock
界面似乎并不那么简单,我想知道是否有更简单的解决方案?或者我不熟悉的对TPL的任何扩展?
答案 0 :(得分:0)
您是否意识到link the blocks with a predicate的可能性?这是一个非常简单且未经过良好测试的样本解决方案:
var buffer = new BufferBlock<int>();
var consumer1 = new ActionBlock<int>(i => Console.WriteLine($"First: {i}"));
var consumer2 = new ActionBlock<int>(i => Console.WriteLine($"Second: {i}"));
var consumer3 = new ActionBlock<int>(i => Console.WriteLine($"Third: {i}"));
var consumer4 = new ActionBlock<int>(i => Console.WriteLine($"Forth: {i}"));
buffer.LinkTo(consumer1, i => Predicate(0));
buffer.LinkTo(consumer2, i => Predicate(1));
buffer.LinkTo(consumer3, i => Predicate(2));
buffer.LinkTo(consumer4, i => Predicate(3));
buffer.LinkTo(DataflowBlock.NullTarget<int>());
for (var i = 0; i < 10; ++i)
{
buffer.Post(i);
}
buffer.Completion.Wait();
其中一项产出:
Third: 2
First: 0
Forth: 3
Second: 1
Second: 5
Second: 9
Third: 6
Forth: 7
First: 4
First: 8
这里发生的是你维持操作次数,如果当前适合消费者,我们只是增加它。请注意,您仍然应该在没有任何谓词的情况下至少链接一次块以避免内存问题(同样,测试带有阻止丢失消息的块的循环是一个好主意。)