有一件事情困扰了我很长时间关于Entity Framework。
去年我为一个客户编写了一个大型应用程序,使用EF进行开发。在开发期间一切都运行良好。
我们在八月份发布了这个系统。但是几周后,我开始在生产服务器上看到奇怪的内存泄漏。我的ASP.NET MVC 4进程在运行几天后(8 GB)占用机器的所有资源。这不是好事。我在网上搜索并发现你应该将所有EF查询和操作包含在 using()
块中,以便可以处理上下文。
一天之内,我重构了所有代码,使用了using()
,这解决了我的问题,自那时起,进程的内存使用率稳定。
然而,我没有一开始就包含查询的原因是,我从Visual Studio中包含的Microsoft自己的脚手架开始我的第一个控制器和存储库,它们没有将查询装入使用中,而是将DbContext
作为控制器本身的实例变量。
首先:如果处理上下文非常重要(这不奇怪,dbconnection
需要关闭等等),那么Microsoft可能应该在所有示例中都这样做!
现在,我已经开始了一个新的大项目,并且将我的所有学习成果放在脑后,我一直在尝试.NET 4.5和EF 6 async
和await
的新功能。EF 6.0具有所有这些异步方法(例如SaveChangesAsync
,ToListAsync
等)。
public Task<tblLanguage> Post(tblLanguage language)
{
using (var langRepo = new TblLanguageRepository(new Entities()))
{
return langRepo.Add(RequestOrganizationTypeEnum, language);
}
}
在类 TblLanguageRepo
中:
public async Task<tblLanguage> Add(OrganizationTypeEnum requestOrganizationTypeEnum, tblLanguage language)
{
...
await Context.SaveChangesAsync();
return langaugeDb;
}
然而,当我现在将我的语句包裹在一个 using()
块中时,我会得到异常 DbContext was disposed
,在查询能够返回之前已经发生了。这是预期的行为。查询运行异步,using
块在查询之前就已经结束。但是,在使用 EF 6 的异步和等待函数时,我应该如何以正确的方式处理上下文的释放?
请指导我正确的方向。
在 EF 6 中是否需要使用 using()
呢?为什么微软自己的示例从未涉及呢?如何使用异步功能并正确地处理上下文的释放?