数据流库有我试图理解的这个选项:ExecutionDataflowBlockOptions.SingleProducerConstrained
我对它的功能进行了测试。令我惊讶的是,它似乎放弃了消息。为什么这不会抛出异常而不是丢弃消息?
[TestMethod]
public void ExecutionDataflowOptions_SingleProducerConstrained()
{
//The failure does not happen each time, so I run it a few times.
for (int iter = 0; iter < 100; iter++)
{
//Create two buffers and one action block.
var buffer1 = new BufferBlock<int>();
var buffer2 = new BufferBlock<int>();
var input = new List<int>(); //A reference type, to be changed by the action block
var transform = new ActionBlock<int>(i => input.Add(i)
, new ExecutionDataflowBlockOptions() { SingleProducerConstrained = true });
buffer1.LinkTo(transform);
buffer2.LinkTo(transform);
//Add two elements, one from each buffer
buffer1.Post(1);
buffer2.Post(2);
Thread.Sleep(100); //added in test, see end
//Violate the SingleProducerConstrained parameter
Parallel.For(0, 100, i => //0, 1, 2
{
var isAccepted1 = buffer1.Post(i);
var isAccepted2 = buffer2.Post(i);
if (!isAccepted1 || !isAccepted2)
throw new Exception(); //This does not error.
});
//Ensure the transform completes (likely not necessary)
transform.Complete();
transform.Completion.Wait();
//Account for all the items: 200 from the Parallel.For + 2 initial
if (202 != buffer1.Count + buffer2.Count + transform.InputCount + input.Count)
throw new Exception(); //Debug point
}
}
答案 0 :(得分:3)
此标志的目的不是强制执行是否有单个生产者。反之。只有当你声明只有一个生产者,所以代码不需要强制执行时,才能进行优化。
设置此标志时,某些块可以删除锁定和同步代码及其开销。但只有你确保有一个生产者。如果你不这样做,可能会有竞争条件,你可能确实会失去信息。
“如果使用块的代码可以保证一次只能由一个生成器(例如链接到块的源)使用,则此属性应该设置为true,这意味着像Post,Complete这样的方法,故障和
OfferMessage
永远不会同时被调用。有些街区可能会选择利用一次只有一个生产者的知识来提供更好的性能。“< / p>
来自ExecutionDataflowBlockOptions.SingleProducerConstrained Property