数据流库有一个我试图理解的选项: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
}
}
最佳答案
此标志的目的不是强制是否有单个生产者。相反。这是为了优化,只有当您声明只有一个生产者时才能进行优化,因此代码不需要强制执行。
当您设置此标志时,某些 block 可以删除锁定和同步代码及其开销。但前提是你确保只有一个制作人。如果不这样做,可能会出现竞争条件,并且您确实可能会丢失消息。
"This property should only be set to true if the code using the block can guarantee that it will only ever be used by one producer (e.g. a source linked to the block) at a time, meaning that methods like Post, Complete, Fault, and
OfferMessage
will never be called concurrently. Some blocks may choose to capitalize on the knowledge that there will only be one producer at a time in order to provide better performance."
来自ExecutionDataflowBlockOptions.SingleProducerConstrained Property
关于c# - TPL 数据流 - ExecutionDataflowBlockOptions.SingleProducerConstrained,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35683767/