SingleProducerConstrained

SingleProducerConstrained

数据流库具有我尝试了解的此选项: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永远不会被同时调用。某些块可能会选择利用一个知识,即一次只有一个生产者,以提供更好的性能。”


来自ExecutionDataflowBlockOptions.SingleProducerConstrained Property

关于c# - TPL数据流-ExecutionDataflowBlockOptions.SingleProducerConstrained,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35683767/

10-13 00:35