我有下面的代码,由两个任务执行,我正在重现两个交易正在进行的行为,并试图从可靠的队列中取出一个项目。
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。 Task1出列并等待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但仍被阻止。我的理解是否正确?或者我在代码中做错了什么?
答案 0 :(得分:1)
IReliableQueue有一些不同的行为,因为它是严格的先进先出(FIFO)。例如,如果您中止Task1的事务,该项将保留在队列的顶部。如果他们允许Task2成功,那么队列顺序将不会被保留,您将成功从队列而不是第一个项目中删除第二个项目。由于这种FIFO行为,IReliableQueue存在许多锁定问题。
如果您不关心订单,请使用ReliableConcurrentQueue。有关两种队列类型之间的更多详细信息,请参阅此article。