在异步/等待代码中重新分配 Transaction.Current 时上下文丢失

Tho*_*sDC 5 .net c# transactionscope async-await 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 :/
}

Run Code Online (Sandbox Code Playgroud)

知道我应该使用using语句TransactionScope而不是重新分配环境事务,但是由于原因,这是不可能的。我很好奇上面代码片段行为的原因,想知道是否有办法保持原始TransactionScopeAsyncFlowOption行为。

Tho*_*sDC 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();
    }
}
Run Code Online (Sandbox Code Playgroud)