如何正确链接多个BufferBlock?多生产者向单消费者传值失败排查
问题根源:数据流链接方向搞反了!
哈哈,一眼就揪出问题啦——你把LinkTo的数据流方向搞反了!LinkTo的逻辑是把「源数据流块(生产者)」的输出,导向「目标数据流块(消费者)」的输入,简单说就是:生产者块.LinkTo(消费者块),而不是反过来。
看你的代码:
var bbA = new BufferBlock<int>(); var bbB = new BufferBlock<int>(); bbB.LinkTo(bbA); // 这里你把bbB设为生产者,bbA设为消费者 bbA.SendAsync(1).Wait(); bbA.SendAsync(2).Wait();
这段代码的意思是:让bbB作为生产者,把它自己的数据传给bbA这个消费者。但你之后却直接往bbA里发数据,这完全不符合你的预期——bbB是生产者端,它只会输出自己生成的数据,不会接收任何外部传入的数据,自然永远是空的。
正确的实现方式
根据你的需求「多个生产者BufferBlock传入一个消费者BufferBlock」,我们需要把每个生产者都链接到同一个消费者块上:
// 定义两个生产者和一个统一的消费者 var producerA = new BufferBlock<int>(); var producerB = new BufferBlock<int>(); var consumerBlock = new BufferBlock<int>(); // 关键:把每个生产者都链接到消费者 producerA.LinkTo(consumerBlock); producerB.LinkTo(consumerBlock); // 往生产者里发送数据 await producerA.SendAsync(1); await producerB.SendAsync(2); // 现在消费者可以接收到数据了 if (consumerBlock.TryReceive(out int data)) { Console.WriteLine($"收到数据:{data}"); // 输出1或2,取决于接收顺序 }
如果你只是想让单个生产者(比如bbA)把数据传给bbB这个消费者,那只要修正链接方向就行:
var bbA = new BufferBlock<int>(); var bbB = new BufferBlock<int>(); // 正确方向:生产者bbA -> 消费者bbB bbA.LinkTo(bbB); await bbA.SendAsync(1); await bbA.SendAsync(2); // 现在bbB里有数据了 if (bbB.TryReceive(out int received)) { Console.WriteLine($"bbB收到:{received}"); }
额外注意事项
- 尽量用
await替代Wait(),避免阻塞线程,让异步流程更顺畅。 - 如果需要生产者完成时通知消费者,可以在
LinkTo时配置PropagateCompletion:
这样当生产者调用producerA.LinkTo(consumerBlock, new DataflowLinkOptions { PropagateCompletion = true });Complete()后,消费者也会收到完成通知,避免一直等待数据。
内容的提问来源于stack exchange,提问作者cubesnyc
相关产品推荐
相关产品推荐

