c# - TPL 数据流 - ExecutionDataflowBlockOptions.SingleProducerConstrained

标签 c# .net task-parallel-library tpl-dataflow

数据流库有一个我试图理解的选项: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/

相关文章:

c# - 从 C++ 调用 C# dll 时如何使用 app.config 文件

c# - REST API 未从 AZURE git 分支下载文件

multithreading - 线程安全 Entity Framework 6

c# - Parallel.For 能否针对运行时间非常短的操作进行优化?

c# - 在具有两个不同参数的线上找到多个匹配绑定(bind)

c# - 任务执行去哪里了?

c# - 如何比较 .NET 中的执行路径?

c# - 如何使用NEST为Elasticsearch指定索引?

c# - 使用默认获取/设置主体创建许多属性的快捷方式

.net - 为什么 NuGet 无法在 TeamBuild 期间恢复单个包,而它在本地运行?