C# TPL BufferBlock.ReceiveAsync接收同一项目两次

C# TPL BufferBlock.ReceiveAsync接收同一项目两次,c#,task-parallel-library,azure-service-fabric,tpl-dataflow,bufferblock,C#,Task Parallel Library,Azure Service Fabric,Tpl Dataflow,Bufferblock,我有一个像这样的缓冲块设置 _inputQueue = new BufferBlock<WorkItem>(new DataflowBlockOptions { BoundedCapacity = 1, CancellationToken = cancellationToken, EnsureOrdered = true }); \u inputQueue=new BufferBlock(new DataflowBlockOptions { 边界容量=1,

我有一个像这样的缓冲块设置

_inputQueue = new BufferBlock<WorkItem>(new DataflowBlockOptions
{
    BoundedCapacity = 1,
    CancellationToken = cancellationToken,
    EnsureOrdered = true
});
\u inputQueue=new BufferBlock(new DataflowBlockOptions
{
边界容量=1,
CancellationToken=CancellationToken,
重新排序=真
});
让多个使用者从不同的线程调用“FetchWork”函数

public async Task<WorkItem> GetWork()
{
    WorkItem wi;
    try
    {
        wi = await _inputQueue.ReceiveAsync(new TimeSpan(0, 0, 1));
    }
    catch (Exception)
    {
        //since we supplied a timeout, this will be thrown if no items come back
        return null;
    }
    return wi;
}
public异步任务GetWork()
{
工作项目wi;
尝试
{
wi=wait_inputQueue.ReceiveAsync(新的时间跨度(0,0,1));
}
捕获(例外)
{
//由于我们提供了一个超时,如果没有项目返回,将抛出该超时
返回null;
}
返回wi;
}

有时,相同的工作项会出现在多个消费者中!InputQueue中的工作项数越多“,在GetWork中收到副本的机会越大。我的理解是,通过ReceiveAsync获取的项目是原子的,一旦某个项目被读取,就不会再被读取。这不是在这里发生的。我有大约40个并行消费者在呼叫GetWork。

这似乎是一个服务结构问题。BufferBlock仅对该项进行一次消隐。生产者[分区计数为5的服务结构有状态服务实例]在不同分区中两次接收相同的项。必须对此进行调查。

为什么不使用DOP为40的ActionBlock或TransformBlock?在任何情况下,你发布的内容都不能说明问题所在。事实上,在
BoundedCapacity=1
的情况下,40名工作人员将一直超时,除非另一侧每秒发送超过40条消息,您是如何确定是否存在重复消息的?项目如何发布到缓冲区块?也许重复的消息只是具有相同数据的不同消息?你能发布一个小样本来实际演示这个问题吗?你刚刚增加了100倍与BufferBlock无关的额外复杂性。BufferBlock不会将这些消息传递给工作者,而Service Fabric会。如果服务结构将同一消息传递给多个工作者,或者同一消息多次到达,则BufferBlock对此无能为力。事实上,当每个工作线程在自己的线程上运行时,为什么要使用缓冲块?即使是队列也可以。在分布式系统中,除非添加额外的机制来处理重复项,否则多次传递始终是一种选择。也许是因为错过了一次确认,基础设施对这条信息感到不满。云服务也没有事务性接收,可以使用租约。也许您忘记了确认收到消息,导致消息在租约到期后重新出现。如果您无法编写一个简单的程序来演示该问题,请查看代码的其余部分。在任何情况下,您都没有发布相关代码。服务结构不使用缓冲块。不知何故,在某个地方,您自己的代码会将内容发布到它。所有基于云的消息传递服务都使用租赁而不是事务性读取,这意味着如果您忘记确认收到消息,它将重新出现在输入队列中