TPL Dataflow - ExecutionDataflowBlockOptions.SingleProducerC
本文关键字:SingleProducerC ExecutionDataflowBlockOptions Dataflow TPL | 更新日期: 2023-09-27 18:36:39
数据流库有这个选项,我试图理解: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
}
}
此标志的目的不是强制是否存在单个生产者。相反。它用于优化,只有当您声明只有一个生产者时才能执行,因此代码不需要强制执行。
设置此标志时,某些块可以删除锁定和同步代码及其开销。但前提是您确保只有一个制片人。如果不这样做,可能会有竞争条件,并且确实可能会丢失消息。
"只有当使用该块的代码可以保证它一次只能由一个生产者(例如链接到块的源)使用时,此属性才应设置为 true,这意味着 Post、Complete、Fault 和
OfferMessage
等方法永远不会同时调用。一些区块可能会选择利用一次只有一个生产者的知识,以提供更好的性能。
From ExecutionDataflowBlockOptions.SingleProducerConstrained Property