我正在尝试将async
/ await
集成到我们的服务总线中。
我根据此示例http://blogs.msdn.com/b/pfxteam/archive/2012/01/20/10259049.aspx实施了SingleThreadSynchronizationContext
。
它工作正常,除了一件事:TransactionScope
。我等待TransactionScope
内的内容,它会打破TransactionScope
。
TransactionScope
似乎与async
/ await
不太匹配,当然因为它使用ThreadStaticAttribute
将内容存储在线程中。我得到了这个例外:
“TransactionScope嵌套错误。”。
我尝试在排队任务之前保存TransactionScope
数据并在运行之前将其恢复,但似乎没有改变任何事情。并且TransactionScope
代码很乱,所以很难理解那里发生了什么。
有没有办法让它发挥作用?是否有TransactionScope
的替代方案?
答案 0 :(得分:154)
在.NET Framework 4.5.1中,有一组new constructors for TransactionScope
采用TransactionScopeAsyncFlowOption
参数。
根据MSDN,它支持跨线程延续的事务流。
我的理解是它允许你编写这样的代码:
// 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();
}
答案 1 :(得分:7)
回答迟到但我遇到了与MVC4相同的问题,我通过右键单击项目将属性从4.5更新到4.5.1。选择应用程序选项卡将目标框架更改为4.5.1并使用事务如下。
using (AccountServiceClient client = new AccountServiceClient())
using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
}
答案 2 :(得分:6)
您可以使用DependentTransaction方法创建的Transaction.DependentClone():
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/