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 了解两种队列类型之间的更多详细信息。
我有以下由两个任务执行的代码,我正在重现两个交易正在进行的行为,并尝试从可靠队列中取出一个项目。
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 了解两种队列类型之间的更多详细信息。