Service Fabric 中 IReliableQueue 的并行出队

Parallel dequeueing of IReliableQueue in Service Fabric

我有以下由两个任务执行的代码,我正在重现两个交易正在进行的行为,并尝试从可靠队列中取出一个项目。

using (var tx = stateManager.CreateTransaction())
{
    LogInfo("{0} Dequeueing at {1}", taskName, DateTime.Now.ToString("hh.mm.ss.ffffff")));
    ConditionalValue<int> result1 = await items.TryDequeueAsync(tx);
    LogInfo("{0} Dequeued at {1}", taskName, DateTime.Now.ToString("hh.mm.ss.ffffff")));      

    if (task == "Task1")
    {        
        await Task.Delay(4000);
    }
    else if (task == "Task2")
    {
        // Do nothing
    }

    await tx.CommitAsync();
}

我先触发 Task1,然后在延迟 1 秒后触发 Task2。任务 1 出列并等待 4 秒。在等待期间,Task2 开始事务并尝试出队。但是,在 Task1 事务完成之前它会被阻塞。

但是文档如下所示:

Transaction is the unit of concurrency: Users can have multiple transactions 
in-flight at any given point of time but for a given transaction each API 
must be called one at a time. So all Reliable Collection APIs that take in a 
transaction and return a Task, must be awaited one at a time

在我的例子中,我在不同的时间为两个任务调用 dequeue,但它仍然被阻塞。我的理解正确吗?或者我在代码中做错了什么?

IReliableQueue 有一些不同的行为,因为它是严格的先进先出 (FIFO)。例如,如果您中止 Task1 的事务,该项目将保留在队列的顶部。如果他们允许 Task2 成功,则不会保留队列顺序,并且您会成功地从队列中删除第二个项目而不是第一个。由于这种 FIFO 行为,IReliableQueue 存在许多锁定问题。

如果您不关心顺序,请使用 ReliableConcurrentQueue. See this article 了解两种队列类型之间的更多详细信息。