我预计最后一个断言中的 result1 在 BroadcastBlock 上与在 BufferedBlock 上一样等于 false,但事实并非如此。
我正在使用最新的 System.Threading.Tasks.Dataflow 版本 8.0.1
var block2 = new BufferBlock<int>(new DataflowBlockOptions { BoundedCapacity = 2 });
var result2 = block2.Post(1);
result2 = block2.Post(1);
Debug.Assert(result2 == true);
result2 = block2.Post(1);
Debug.Assert(result2 == false); // this is expected and work
var block1 = new BroadcastBlock<int>(i => i, new DataflowBlockOptions { BoundedCapacity = 2});
var result1 = block1.Post(1);
result1 = block1.Post(1);
Debug.Assert(result1 == true);
result1 = block1.Post(1);
Debug.Assert(result1 == false); // this fails
这是一个错误还是预期的?
阅读源,看起来
BroadcastBlock
将新消息添加到内部队列,然后异步尝试将其转发给所有消费者。一旦完成,它就会将其从内部队列中删除。
如果您在内部队列上设置了容量(使用
BoundedCapacity
),并且该队列已满(因此您添加项目的速度比向所有消费者提供项目的速度快),那么 Post
将返回错误。
在您的测试中,由于提供商品的任务是在后台线程上异步发生的,因此添加商品的速度与向所有消费者提供商品的速度之间存在竞争。在 DotNetFiddle 上,您的 final
Post
返回 false,但是,如果我在最终 .Post
之前添加睡眠(让后台线程有机会清除内部队列),则 final Post
返回 true。