TPL 区块循环 link?

TPL Block with round robin link?

我经常使用 TPL 并且拥有大数据流管道结构。
作为管道网络的一部分,我想将一些数据写入 azure blob 存储。我们有大量数据,因此我们有 4 个存储帐户,我们希望在它们之间平均分配数据。

想继续使用数据流管道模式,因此我想实现一个 SourceBlock,如果我 link 将它发送到多个目标块,它将通过循环将消息发送给它们。 BufferBlock 不够好,因为他将消息发送到第一个接受它的块,并假设所有目标块都具有大的有界容量 - 所有消息都将发送到第一个目标块。 BroadcastBlock 也不好,因为我不想重复。

有什么建议吗?实现具有循环行为的 ISourceBlock 接口似乎并不那么简单,我想知道是否有更简单的解决方案?或任何我不熟悉的 TPL 扩展?

你知道 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

这里发生的事情是你要维持操作的数量,如果当前适合消费者,我们就增加它。请注意,您仍然应该 link 至少一次没有任何谓词的块以避免内存问题(另外,用块来测试循环是一个好主意,它确实监视丢失的消息)。