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

C# 在异步/等待代码中重新分配Transaction.Current时,上下文丢失,c#,.net,async-await,transactionscope,rebus,C#,.net,Async Await,Transactionscope,Rebus,重新分配Transaction.Current时,我似乎丢失了我的TransactionScope的原始TransactionScope AsyncFlowOption行为。第二次wait后的代码将丢失其事务。当前值 示例代码(Linqpad): 我应该在TransactionScope上使用using语句,而不是重新分配环境事务,但是由于种种原因,不可能这样做。我很好奇上面代码段行为的原因,想知道是否有办法保持原始的TransactionScopeAsyncFlowOption行为。我通过将事

重新分配
Transaction.Current
时,我似乎丢失了我的
TransactionScope
的原始
TransactionScope AsyncFlowOption
行为。第二次
wait
后的代码将丢失其
事务。当前值

示例代码(Linqpad):


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

我通过将
事务
对象包装在另一个
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();
    }
}

你在哪里运行代码?我尝试了LINQPad,如果我没有设置
事务,Current
我总是得到相同的事务。看起来像是
事务的setter的实现。Current
总是使用TLS上下文,而不是异步兼容上下文。
TransactionScope
构造函数(特别是
PushScope
)的实现不会设置任何一个。看起来您必须打开一个bug报告。可以在dotnet/corefx中找到相关的bug报告。太棒了!您已经以pull请求的形式提交了修复,我已经接受并发布为Rebus.TransactionScopes 5.0.0-b2–谢谢!
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();
    }
}