获取TransactionScope以使用async/await

Yan*_*ann 110 c# transactionscope async-await

我正在尝试整合async/ await进入我们的服务总线.我SingleThreadSynchronizationContext基于这个例子http://blogs.msdn.com/b/pfxteam/archive/2012/01/20/10259049.aspx实现了一个.

它的工作正常,除了一件事:TransactionScope.我等待内部的东西TransactionScope,它打破了TransactionScope.

TransactionScope似乎并没有与async/ 好玩await,当然因为它使用的东西存储在线程中ThreadStaticAttribute.我得到这个例外:

"TransactionScope嵌套不正确."

TransactionScope在排队任务之前尝试保存数据并在运行之前将其恢复,但它似乎没有改变.和TransactionScope代码是一个烂摊子,所以真的很难理解发生了什么事情在那里.

有没有办法让它发挥作用?有替代品TransactionScope吗?

Zun*_*Tzu 157

在.NET Framework 4.5.1中,有一组新的构造函数用于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();
}
Run Code Online (Sandbox Code Playgroud)


Atu*_*ary 7

回答迟到但我遇到了与MVC4相同的问题,我通过右键单击项目将属性从4.5更新到4.5.1.选择应用程序选项卡将目标框架更改为4.5.1并使用事务如下.

using (AccountServiceClient client = new AccountServiceClient())
using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
}
Run Code Online (Sandbox Code Playgroud)

  • 这与[接受的答案有什么不同?](/sf/answers/1226943161/) (3认同)

max*_*mpa 6

您可以使用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();
}
Run Code Online (Sandbox Code Playgroud)

使用DependentTransaction管理并发

http://adamprescott.net/2012/10/04/transactionscope-in​​-multi-threaded-applications/

  • Adam Prescott的示例子任务未标记为异步.如果用"await Task.Delay(500)"之类的东西替换"do transactional stuff",这个模式也会因`TransactionScope嵌套不正确'而失败,因为最外面的TransactionScope(上例中没有显示)在子任务正确之前退出范围完成.将`await`替换为`Task.Wait()`并且它可以工作,但是你失去了`async`的好处. (2认同)