【问题标题】:Async/Await questions with Entity Framework and refactoring实体框架和重构的异步/等待问题
【发布时间】:2014-05-09 20:06:28
【问题描述】:

我正在开始一个新项目,并希望利用 .NET 中的 async/await 项以及实体框架(6.1 版)中的新 Async 操作。但是,我很好奇的是如何重构我的应用程序的某些部分以减少代码重复,以及考虑到 EF 的非线程安全性质,实现这一点的最佳方法。

例如,我的服务层中有一些方法看起来像这样

public async Task<MyViewModel> GetProgramIndexAsync(long programId){
            using (var db = new DbEntities())
            {
                var program = await db.Programs.FirstOrDefaultAsync(x => x.Id == programId && x.Active);
                if (program == null)
                {
                    throw new ApplicationException("Cannot find the requested program");
                }
            //more code to populate the view model
            }
        }

到目前为止,一切都很好。但是我发现自己在这个服务层的多个地方都在做这个检查。理想的做法是将其提取到单独的函数中

private async Task<Program> GetProgramAsync(long programId){
            using (var db = new DbEntities())
            {
                var program = await db.Programs.FirstOrDefaultAsync(x => x.Id == programId && x.Active);
                if (program == null)
                {
                    throw new ApplicationException("Cannot find the requested program");
                }
            return program;
            }
        }

现在,我的公共服务层调用可以简单地调用这个函数,而不必每次都重复这个检查。

var program = await GetProgramAsync(programId);

我担心的是这些请求中的每一个都会启动多个上下文。在过去(同步),我可以简单地拥有第二个函数参数,例如

private async Task<Program> GetProgramAsync(long programId, DbContext db){

并将现有的上下文传递给方法。但是,我假设这对于 async/await 的性质会很糟糕。

我是不是在想这个(多个上下文并没有那么糟糕)还是有更好的方法来完成这个?请注意,这些调用是只读的,我不会以这种方式更新实体。

【问题讨论】:

    标签: c# entity-framework asynchronous


    【解决方案1】:

    你认为自己遇到的问题都不是问题。

    1. 借助连接池,启动多个上下文并不是真正的问题。创建一个新的上下文实际上并不需要创建一个新的数据库连接,它只是从池中获取一个。如果您在即将需要新的连接之前将其放回池中,而不是保持大量 并发 连接,则开销非常小。

      李>
    2. 如果您确实在这些方法之间传递上下文,它仍然不是问题。代码是异步的,但它没有并行执行任何操作。上下文一次只能由一个线程使用。您总是在等待任何可能是异步的操作,这意味着虽然与这些方法完全相关的其他代码可能正在使用 CPU,无论是另一个响应处理程序(如果这是 ASP),UI 泵送其他事件(如果这是一个桌面应用程序)或其他东西,您仍然无法同时从多个线程访问此上下文

    【讨论】:

    • 谢谢!我想我可能稍微误解了异步的工作流程以及它对 EF 的影响,但我不想走那条路,只是不得不取消重构所有内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-08
    • 1970-01-01
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 2018-12-09
    • 2015-02-24
    相关资源
    最近更新 更多