如何在.NET 4.0中使用Microsoft.Bcl.Async支持TransactionScope中的异步方法?

Mat*_*int 22 .net c# .net-4.0 transactionscope async-await

我有一个类似的方法:

public async Task SaveItemsAsync(IEnumerable<MyItem> items)
{
    using (var ts = new TransactionScope())
    {
        foreach (var item in items)
        {
            await _repository.SaveItemAsync(item);
        }

        await _repository.DoSomethingElse();

        ts.Complete();
    }
}
Run Code Online (Sandbox Code Playgroud)

这当然有问题,因为TransactionScopeasync/await不能很好用.

它失败并显示InvalidOperationException消息:

"TransactionScope必须放在与它创建的同一个线程上."

TransactionScopeAsyncFlowOption这个答案中读到了,这似乎正是我所需要的.

但是,对于这个特定项目,我很难支持.Net 4.0,无法升级到4.5或4.5.1.因此,我的项目中的异步/等待行为由Microsoft.Bcl.Async NuGet包提供.

我似乎无法TransactionScopeAsyncFlowOption在这个或任何其他OOB包中找到.我只是在某个地方错过了吗?

如果没有,是否有其他方法可以达到相同的效果?也就是说 - 我希望事务范围正确完成或回滚,尽管跨越线程有延续.

DoSomethingElse在上面的示例中添加了说明在事务范围内可能有多个调用,因此在一次调用中简单地将所有项目传递给数据库是不可行的选择.

在它的事项的情况下,库使用直接ADO.Net( ,SqlConnection,SqlCommand等)写入到SQL Server.

UPDATE

我以为我有一个解决方案,涉及从.Net 4.5.1中获取System.Transactions.dll并将其包含在我的项目中.但是,我发现这只适用于我的开发盒,因为它已经安装了4.5.1.部署到仅具有.Net 4.0的计算机时,它不起作用.它只是给了一个MissingMethodException.我正在寻找一种适用于.Net 4.0安装的解决方案.

小智 22

你必须使用 TransactionScopeAsyncFlowOption.Enabled

public static TransactionScope CreateAsyncTransactionScope(IsolationLevel isolationLevel = IsolationLevel.ReadCommitted)
    {
        var transactionOptions = new TransactionOptions
        {
            IsolationLevel = isolationLevel,
            Timeout = TransactionManager.MaximumTimeout
        };
        return new TransactionScope(TransactionScopeOption.Required, transactionOptions, TransactionScopeAsyncFlowOption.Enabled);
    }
Run Code Online (Sandbox Code Playgroud)

  • 重要说明:TransactionScopeAsyncFlowOption仅适用于.net framework 4.5.1或更高版本http://particular.net/blog/transactionscope-and-async-await-be-one-with-the-flow (4认同)