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();
}
}