我是否正确使用 DataContext.Dispose() ?

发布于 2024-10-02 19:05:15 字数 381 浏览 2 评论 0原文

我在 ASP.NET MVC 项目中遇到了大量连接池超时问题。我一直在读到,尽管 Linq-to-SQL 应该为我进行处置,但它并不总是有效,而且不手动处置继承 IDisposable 的任何内容都是不好的做法。

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

public void SubmitChanges()
{
    db.SubmitChanges();
    db.Dispose();
}

这是一个好地方吗?这样做还是我做的完全错误?

I've been getting lots of connection pool timeouts in my ASP.NET MVC project. I've been reading that even though Linq-to-SQL should be disposing for me it doesn't always work and also that not manually disposing anything that inherits IDisposable is bad practice.

I'm using the repository pattern that all my Linq-to-SQL statements use. Not knowing where to put the DataContext.Dispose() method, I put it in the SubmitChanges() function that consists of two lines of code:

public void SubmitChanges()
{
    db.SubmitChanges();
    db.Dispose();
}

Is this a good place to do this or am I doing it completely wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一花一树开 2024-10-09 19:05:15

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

using(var context = new DataContext()){
  blah blah
}

这确保它在适当的时间被处置。

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

这样您就不必担心它会挂起,并且不会因为异常等而被调用。

dispose 关键字(MSDN 链接)

由于它们是相关的,这里有一个关于Dispose and Finalize的链接。听起来在这种情况下,您想要实现存储库,以便它实现 IDisposable。这样调用对象就可以创建它,执行它需要执行的操作并关闭它。然后,您可以在处理/完成数据上下文时清理数据上下文。

If it implements IDisposable the easiest way to do it is:

using(var context = new DataContext()){
  blah blah
}

This ensures it is disposed at the appropriate time.

  1. Open it.
  2. Do what you need to do.
  3. Close it.

This way you don't have to worry about it hanging around, and not getting called because of an exception etc.

The dispose key word (MSDN Link).

Since they are related, here is a link about Dispose and Finalize. It sounds like in this case, you want to implement the Repository so that it implements IDisposable. This way the calling object can create it, do what it needs to do and close it. You then can clean up the data context when it is disposed/finalized.

攒眉千度 2024-10-09 19:05:15

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

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 的对象。

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

因此,我按照 Craig 的建议进行操作,并覆盖了 Controller 继承的 Dispose 方法。

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

    Repository repository;

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

    protected override void Dispose(bool disposing)
    {
        repository.Dispose();
    }

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

    public void Dispose()
    {
        db.Dispose();
    }

其中 db 是我的 DataContext

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

Well after some more digging I came across this post:

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

and in the comments section Craig Stuntz wrote:

Failing to Dispose an object which implements IDisposable typically results in the object going into the finalization queue (read Chapter 19 of Jeffrey Richter's Applied Microsoft .NET Framework Programming for details). The results of this is that an object's memory that might have otherwise been freed in generation 01 be freed until a later generation collection. If you're creating a lot of these objects, well, do the math.

So you should always Dispose any object which implements IDisposable.

In the case of Controllers and DataContexts, this turns out to be really easy, because Controller also implements IDisposable, and hence has a virtual Dispose method you can override. So you don't have to wrap your use of DataContext in a using. You can create it in the constructor (or wherever) and then dispose in the overridden Controller.Dispose. In this case, using IQueryable in the view works just fine, because the framework does not Dispose the Controller until the View has been rendered.

So I did what Craig suggested and overrode the Dispose method that the Controller inherits.

At the top of my controller code:

    Repository repository;

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

    protected override void Dispose(bool disposing)
    {
        repository.Dispose();
    }

and in my Repository I have a method called Dispose that looks like:

    public void Dispose()
    {
        db.Dispose();
    }

where db is my DataContext.

Now my overriden Dispose method gets called every time :) and I don't have to wrap all my ActionResult in using blocks

萌无敌 2024-10-09 19:05:15

DataContext(您的存储库)必须实现IDisposable

理想情况下,您需要一个 UnitOfWork 来传递到存储库并实现 IDisposable。在这里,您将其留给客户端调用另一个不好的方法。

DataContext (your repository) must implement IDisposable.

Ideally you need a UnitOfWork to pass to repositories and that implements IDisposable. Here you are leaving it down to the client to call another method which is not good.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文