如何在.NET 4.0中使用Microsoft.Bcl.Async在TransactionScope中支持异步方法? [英] How to support async methods in a TransactionScope with Microsoft.Bcl.Async in .NET 4.0?

查看:216
本文介绍了如何在.NET 4.0中使用Microsoft.Bcl.Async在TransactionScope中支持异步方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有类似的方法:

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

这当然有问题,因为 TransactionScope 在异步/等待过程中不能很好地发挥作用。

This of course has issues because TransactionScope doesn't play nice with async/await.

由于出现 InvalidOperationException 并显示消息:


必须将TransactionScope置于创建它的同一线程上。

"A TransactionScope must be disposed on the same thread that it was created."

我读到有关 此答案 TransactionScopeAsyncFlowOption >,这似乎正是我所需要的。

I read about TransactionScopeAsyncFlowOption in this answer, which appears to be exactly what I need.

但是,对于此特定项目,我对支持.Net 4.0有硬性要求,不能升级到4.5或4.5 .1。因此,我的项目中的异步/等待行为由 Microsoft.Bcl.Async NuGet提供包

However, for this particular project, I have a hard requirement to support .Net 4.0 and cannot upgrade to 4.5 or 4.5.1. Thus the async/await behavior in my project is provided by the Microsoft.Bcl.Async NuGet Package.

我似乎在此或任何其他TransactionScopeAsyncFlowOption = http://msdn.microsoft.com/en-us/library/dn151288.aspx rel = nofollow noreferrer> OOB软件包。我只是在某个地方想念它吗?

I can't seem to find TransactionScopeAsyncFlowOption in this or any other OOB package. Am I just missing it somewhere?

如果不可用,是否有替代方法可以实现相同的结果?那就是-我希望事务范围能够正确完成或回滚,尽管线程之间有连续性。

If it is not available, is there an alternative for achieving the same result? That is - I would like the transaction scope to properly complete or rollback, despite crossing threads with continuations.

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

I added DoSomethingElse in the example above to illustrate that there may be multiple calls to make within the transaction scope, so simply passing all items to the database in one call is not a viable option.

如果有关系,存储库将使用直接ADO.Net( SqlConnection SqlCommand 等)编写

In case it matters, the repository uses direct ADO.Net (SqlConnection, SqlCommand, etc) to write to a SQL Server.

UPDATE 1

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

I thought I had a solution which involved taking System.Transactions.dll from .Net 4.5.1 and including it in my project. However, I found that this worked only on my dev box because it already had 4.5.1 installed. It did not work when deploying to a machine with only .Net 4.0. It just gave a MissingMethodException. I'm looking for a solution that will work on a .Net 4.0 installation.

UPDATE 2

我最初在2014年7月问这个问题。.NET Framework 4.0、4.5和4.5.1已达到报废,于2016年1月结束。因此,该问题不再适用,此处仅作历史参考。

I originally asked this question in July 2014. .NET Framework 4.0, 4.5, and 4.5.1 reached end of life in January 2016. The question thus is no longer applicable and is here only for historical reference.

推荐答案

您必须使用 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);
    }

这篇关于如何在.NET 4.0中使用Microsoft.Bcl.Async在TransactionScope中支持异步方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆