重新分配事务时上下文丢失。异步/等待代码中的当前

时间:2019-05-02 15:00:26

标签: c# .net async-await transactionscope rebus

重新分配Transaction.Current时,我似乎失去了TransactionScopeAsyncFlowOption原来的TransactionScope行为。第二个await之后的代码丢失了Transaction.Current值。

示例代码(Linqpad):

async Task Main()
{
    Thread.CurrentThread.ManagedThreadId.Dump("before await");
    var scope = new TransactionScope(TransactionScopeOption.Required, TransactionScopeAsyncFlowOption.Enabled);
    var transaction = Transaction.Current;

    await Task.Delay(1000).ConfigureAwait(false);

    Thread.CurrentThread.ManagedThreadId.Dump("after first await");
    Transaction.Current = transaction;
    Transaction.Current.Dump(); // not null

    await Task.Delay(1000).ConfigureAwait(false);

    Thread.CurrentThread.ManagedThreadId.Dump("after second await");
    Transaction.Current.Dump(); // is null :/
}

know应该在using上使用TransactionScope语句,而不是重新分配环境事务,但是由于某些原因,不可能这样做。我对以上代码段行为的原因感到好奇,并想知道是否存在保持原始TransactionScopeAsyncFlowOption行为的方法。

1 个答案:

答案 0 :(得分:1)

我通过将Transaction对象包装到另一个TransactionScope中并启用了TransactionScopeAsyncFlowOption来解决了这个问题:

async Task Main()
{
    var scope = new TransactionScope(TransactionScopeOption.Required, TransactionScopeAsyncFlowOption.Enabled);
    var transaction = Transaction.Current;

    await Task.Delay(1000);

    Transaction.Current = transaction;
    Debug.Assert(Transaction.Current != null); // not null

    await Task.Delay(1000);

    Debug.Assert(Transaction.Current == null); // is null :/

    using (var innerScope = new TransactionScope(transaction, TransactionScopeAsyncFlowOption.Enabled))
    {
        // Transaction.Current state is kept across async continuations
        Debug.Assert(Transaction.Current != null); // not null
        await Task.Delay(10);
        Debug.Assert(Transaction.Current != null); // not null
        innerScope.Complete();
    }
}