C# 获取 TransactionScope 以使用 async/await
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13543254/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get TransactionScope to work with async / await
提问by Yann
I'm trying to integrate async/awaitinto our service bus.
I implemented a SingleThreadSynchronizationContextbased on this example http://blogs.msdn.com/b/pfxteam/archive/2012/01/20/10259049.aspx.
我正在尝试将async/集成await到我们的服务总线中。我SingleThreadSynchronizationContext基于这个例子实现了一个http://blogs.msdn.com/b/pfxteam/archive/2012/01/20/10259049.aspx。
And it works fine, except for one thing: TransactionScope. I await for stuff inside the TransactionScopeand it break the TransactionScope.
它工作正常,除了一件事:TransactionScope. 我等待里面的东西TransactionScope,它打破了TransactionScope.
TransactionScopedoesn't seems to play nice with the async/await, certainly because it store things in the thread using ThreadStaticAttribute. I get this exception :
TransactionScope似乎不适合async/ await,当然是因为它使用ThreadStaticAttribute. 我得到这个例外:
"TransactionScope nested incorrectly.".
“TransactionScope 嵌套不正确。”。
I tried to save TransactionScopedata before queuing the task and restore it before running it but it doesn't seems to change a thing. And TransactionScopecode is a mess, so it's really hard to understand what's going on there.
我试图TransactionScope在排队任务之前保存数据并在运行它之前恢复它,但它似乎没有改变任何事情。而且TransactionScope代码一团糟,所以很难理解那里发生了什么。
Is there a way to make it work ? Is there some alternative to TransactionScope?
有没有办法让它工作?有TransactionScope什么替代品吗?
回答by maximpa
You can use DependentTransactioncreated by Transaction.DependentClone()method:
您可以使用由Transaction.DependentClone()方法创建的DependentTransaction:
static void Main(string[] args)
{
// ...
for (int i = 0; i < 10; i++)
{
var dtx = Transaction.Current.DependentClone(
DependentCloneOption.BlockCommitUntilComplete);
tasks[i] = TestStuff(dtx);
}
//...
}
static async Task TestStuff(DependentTransaction dtx)
{
using (var ts = new TransactionScope(dtx))
{
// do transactional stuff
ts.Complete();
}
dtx.Complete();
}
Managing Concurrency with DependentTransaction
http://adamprescott.net/2012/10/04/transactionscope-in-multi-threaded-applications/
http://adamprescott.net/2012/10/04/transactionscope-in-multi-threaded-applications/
回答by ZunTzu
In .NET Framework 4.5.1, there is a set of new constructors for TransactionScopethat take a TransactionScopeAsyncFlowOptionparameter.
在 .NET Framework 4.5.1 中,有一组用于TransactionScope接受TransactionScopeAsyncFlowOption参数的新构造函数。
According to the MSDN, it enables transaction flow across thread continuations.
根据 MSDN,它支持跨线程延续的事务流。
My understanding is that it is meant to allow you to write code like this:
我的理解是,它旨在允许您编写这样的代码:
// transaction scope
using (var scope = new TransactionScope(... ,
TransactionScopeAsyncFlowOption.Enabled))
{
// connection
using (var connection = new SqlConnection(_connectionString))
{
// open connection asynchronously
await connection.OpenAsync();
using (var command = connection.CreateCommand())
{
command.CommandText = ...;
// run command asynchronously
using (var dataReader = await command.ExecuteReaderAsync())
{
while (dataReader.Read())
{
...
}
}
}
}
scope.Complete();
}
回答by Atul Chaudhary
Bit late for an answer but I was having the same issue with MVC4 and I updated my project from 4.5 to 4.5.1 by right clicking on project go to properties. Select application tab change target framework to 4.5.1 and use transaction as follow.
回答有点晚了,但我在 MVC4 中遇到了同样的问题,我通过右键单击项目转到属性将我的项目从 4.5 更新到 4.5.1。选择应用程序选项卡将目标框架更改为 4.5.1 并使用事务如下。
using (AccountServiceClient client = new AccountServiceClient())
using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
}

