C# EF事务和异步

C# EF事务和异步,c#,entity-framework,asynchronous,C#,Entity Framework,Asynchronous,我正在ASP.NETMVC中使用EF6。我在后台运行一些任务,所以我使用一个新的EF上下文和任务类来执行它。异步任务分为3个较小的任务,这些任务也应在同一个DB事务中运行异步。我无法使用SaveAsync,因为我的代码是从同步和异步上下文调用的 Task.Run(() => { try { using (var transaction = dbContext.Da

我正在ASP.NETMVC中使用EF6。我在后台运行一些任务,所以我使用一个新的EF上下文和任务类来执行它。异步任务分为3个较小的任务,这些任务也应在同一个DB事务中运行异步。我无法使用SaveAsync,因为我的代码是从同步和异步上下文调用的

Task.Run(() =>
            {
                try
                {
                    using (var transaction = dbContext.Database.BeginTransaction())
                    {
                        CalculateAmounts(id);

                        transaction.Commit();
                    }
                }
                finally
                {
                    dbContext.Dispose();
                }
            });
CalculateAmounts方法创建了3个以上的任务。我应该如何处理这些交易


另一方面,当任务一起工作时,我会遇到一些错误,比如DataReader已经打开了。我应该为每个任务创建上下文吗?在这种情况下,如何使它们都成为同一笔交易的一部分?

恐怕你不能随心所欲,原因如下:

异步任务分为3个较小的任务,它们也应该运行 异步但在同一个DB事务中

单个数据库连接一次只能运行一个事务。这意味着您需要3个并发连接

您仍然可以使用一个包装器包装这3个连接。问题是TransactionScope对任何线程都是不可见的,而该线程不是启动它的线程。实际上,TS是线程静态的,ADO.NET会检查它的当前线程,以确定它是应该同时提交多个事务还是将它们全部回滚。不管怎样,这对你不起作用

从.NET 4.5.1开始,有一个选项可以将
TransactionScopeAsyncFlowOption
传递给TransactionScope,但它不支持内部的多线程。它只支持
async/await


TL;DR:最好是并行地完成所有工作,然后以串行方式提交所有工作。

任务。在ASP.NET应用程序中,运行几乎从来都不是一个好主意。您可能正在制作无法保证在AppDomain关闭之前完成的任务,或者只是增加了开销并降低了网站的可扩展性。如果您考虑长时间运行的任务,我认为您的评论是正确的。我说的是不到10秒的任务。如果AppDomain关闭,在任何情况下都将是一场灾难(只在一个线程或多个线程中执行)。您建议任务不保存任何内容,当所有任务都完成后,我将保存到DB并提交?问题是我正在运行一个ASP.NETMVC应用程序,任务允许我在后台做一些事情时将页面返回给用户。至于TransactionScope,Microsoft建议从EF6开始使用dbContext.Database.BeginTransaction。是的,这就是我的建议。是的,大多数情况下都应该使用dbContext.Database.BeginTransaction。如果你想在一个全局分布式事务中提交多个内部事务,你仍然要绑定到TransactionScope。“问题是我正在运行ASP.NET MVC应用程序,任务允许我在后台执行某些操作时将页面返回给用户。”我无法等待所有任务。我做一些同步的事情,在后台启动任务,并返回带有中间结果(同步计算的结果)的页面。我希望能够返回中间结果,同时可以继续处理大型事务。