0

在服务结构有状态服务中,有 RunAsync(cancellationToken) 和 using() 用于状态管理器事务。

我要重构的遗留代码包含两个队列,在 while(true) 内尝试出队,延迟时间为 1 秒。我想摆脱这种不必要的延迟,而是使用两个不同的反应队列(具有可靠队列的信号量)。

问题是,现在需要将依赖于这两个队列的两个不同的工作流分成两个单独的线程,因为如果这两个队列在单个线程中运行,一个 wait() 将阻止其他代码运行。(我知道最好的做法可能是将这两个任务分成两个微服务,下一个项目。)

我想出了以下代码作为解决方案:

    protected override async Task RunAsync(CancellationToken cancellationToken)
    {
        await Task.WhenAll(AsyncTask1(cancellationToken), AsyncTask2(cancellationToken)).ConfigureAwait(false);
    }

每个任务都包含以下内容:

    while (true)
    {
        cancellationToken.ThrowIfCancellationRequested();

        using (var tx = this.StateManager.CreateTransaction())
        {
            var maybeMessage = await messageQueue.TryDequeueAsync(tx, cancellationToken).ConfigureAwait(false);

            if (maybeMessage.HasValue)
            {
                DoWork();
            }

            await tx.CommitAsync().ConfigureAwait(false);
        }
    }

似乎有效,但我只想确保 using(statemanger.createTansaction()) 可以以这种并行方式使用..

4

1 回答 1

1

根据文档

根据单条目操作的副本角色(如TryDequeueAsync),ITransaction使用可重复读取隔离级别(当主要时)或快照隔离级别(当 **次要时)。


可重复读取

默认情况下,任何可重复读取操作都需要共享锁。

快照

使用快照隔离完成的任何读取操作都是无锁的。


因此,如果DoWork不修改可靠集合,则可以并行执行多个事务而没有问题。

在多次读取/更新的情况下 - 这可能会导致死锁,应小心操作。

于 2018-10-11T13:11:02.357 回答