我正确使用DataContext.Dispose()吗?

Dar*_*rcy 5 c# repository-pattern linq-to-sql

我在ASP.NET MVC项目中获得了大量的连接池超时.我一直在阅读,即使Linq-to-SQL应该为我处理它并不总是有效,而且不手动处理任何继承的东西IDisposable都是不好的做法.

我正在使用我的所有Linq-to-SQL语句都使用的存储库模式.不知道把DataContext.Dispose()方法放在哪里,我把它放在SubmitChanges()由两行代码组成的函数中:

public void SubmitChanges()
{
    db.SubmitChanges();
    db.Dispose();
}
Run Code Online (Sandbox Code Playgroud)

这是一个做这个的好地方还是我完全错了?

kem*_*002 8

如果它实现了IDisposable,最简单的方法是:

using(var context = new DataContext()){
  blah blah
}
Run Code Online (Sandbox Code Playgroud)

这确保了它在适当的时间处理.

  1. 打开它.
  2. 做你需要做的事.
  3. 关闭它.

这样你就不必担心它会徘徊,也不会因异常而被调用.

配置关键字(MSDN Link).

由于它们是相关的,因此这里有一个关于Dispose和Finalize的链接.听起来在这种情况下,您希望实现存储库,以便它实现IDisposable.通过这种方式,调用对象可以创建它,执行它需要做的事情并关闭它.然后,您可以在处理/完成数据上下文时清理它.


Dar*_*rcy 2

经过更多挖掘后,我发现了这篇文章:

http://stephenwalther.com/blog/archive/2008/08/20/asp-net-mvc-tip-34-dispose-of-your-datacontext-or-don-t.aspx

Craig Stuntz 在评论部分写道:

未能释放实现 IDisposable 的对象通常会导致该对象进入终结队列(有关详细信息,请阅读 Jeffrey Richter 的《应用 Microsoft .NET Framework 编程》第 19 章)。这样做的结果是,本来可能在第 01 代中释放的对象内存将被释放,直到稍后的代回收为止。如果您要创建很多这样的对象,那么请计算一下。

因此,您应该始终释放任何实现 IDisposable 的对象。

对于控制器和 DataContext 来说,这非常简单,因为控制器还实现了 IDisposable,因此有一个可以重写的虚拟 Dispose 方法。因此,您不必将 DataContext 的使用包装在 using 中。您可以在构造函数(或任何地方)中创建它,然后在重写的 Controller.Dispose 中进行处理。在这种情况下,在视图中使用 IQueryable 效果很好,因为框架在渲染视图之前不会释放控制器。

所以我按照克雷格的建议做了并重写了继承的Dispose方法Controller

在我的控制器代码的顶部:

    Repository repository;

    // Default Contructor
    public MyController()
    {
        repository = new Repository();
    }

    protected override void Dispose(bool disposing)
    {
        repository.Dispose();
    }
Run Code Online (Sandbox Code Playgroud)

在我的存储库中,我有一个名为 Dispose 的方法,如下所示:

    public void Dispose()
    {
        db.Dispose();
    }
Run Code Online (Sandbox Code Playgroud)

其中 db 是我的DataContext.

现在我的重写 Dispose 方法每次都会被调用:)并且我不必将所有内容包装ActionResult在 using 块中