为什么asp.net MVC控制器需要显式Dispose()方法?有人可以解释一下吗?(具体针对asp.net)

32

我知道C#可以通过其垃圾回收器很好地管理资源。但既然有了这个,那它到底是用来做什么的,为什么需要它?

有人能解释一下为什么在asp.net mvc中需要.Dispose()吗?

此外,什么是Dispose一个连接的意思?为什么需要这样做?是否有人了解为什么像db.Dispose()这样处理数据库连接很重要的复杂性?这与EF相关还是与SQL Server相关?我正在尝试准确理解为什么。

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

2
通常情况下,如果它是 IDisposable 类型,并且你持有任何 IDisposable 类型的对象,请提供一个 Dispose 方法。并使用它。 - cHao
我听说过这个……但是为什么呢?C#不是有一个垃圾回收器吗?一旦对象超出范围,它就会销毁不需要的对象。那么,为什么在asp.net mvc的控制器中还需要显式的.Dispose()方法?甚至在Entity Framework中也是如此?它到底是做什么用的? - Jan Carlo Viray
可能是C# Finalize/Dispose模式的重复问题。请查看IDisposable标签的热门答案(在使用和实现IDisposable方面与MVC无关)。 - Alexei Levenkov
@JanCarloViray - 它允许您控制未受管理的资源何时被处理(例如那些不会被垃圾回收的资源)。 - M.Babcock
3
@AlexeiLevenkov:这并不是完全重复的问题。将具体问题作为更一般、教程式问题的副本关闭,道德上等同于说“RTFM”。请参见http://meta.stackexchange.com/a/110002/102937。OP特别询问了Dispose()方法在MVC控制器中的意义和用途。换句话说,你为什么需要在那里使用Dispose模式?它到底处置什么? - Robert Harvey
1个回答

31

Dispose 方法用于释放“非托管”资源(例如,套接字、文件句柄、位图句柄等),并且如果在终结器之外调用它(顺便说一下,“disposing”标志表示这一点),则用于处理不再有用的其他 IDisposable 对象。

“非托管”资源不由 CLR(公共语言运行时)管理(因此得名),GC (垃圾回收机制)不会自己处理或释放它们;如果一个对象没有 Dispose 方法(以及使用它的代码!),它将依赖于对象的终结器进行清理。最终终结器会运行(如果应用程序健康,且对象具有终结器),如果终结器执行其工作,则一切都差不多……但是这需要很长时间,如果在此期间耗尽了句柄,就太糟糕了。那些需要它们的其他线程/进程/组件将无法继续运行。

但是如果您使用 Dispose,则资源会立即释放,并且所有操作都变得更加顺畅。

(顺便说一下,这不仅适用于 EF、SQL Server 或任何其他技术。可处置模式遍布整个 .net 框架,而且每当您有一个不再使用的 IDisposable 时,利用它被认为是一种良好的实践。)

关于为什么实现IDisposable在类的层级较高处,而不是按需逐个实现的原因,我还不能百分之百确定。但是想象一下,如果你正在编写一个框架,考虑到如果不是每个对象都实现IDisposable接口,每次想要摆脱某个对象时都必须检查该对象是否可释放并进行处理。如果您将IDisposable接口“预先实现”,则简化了事情——您只需总是进行处理。(如果一个对象没有任何清理工作,则不需要覆盖 Dispose 方法,此时将调用其父对象的Dispose方法,并执行其所需的任何清理工作,这可能也是无操作的...)而且控制器通常会有一些需要清理的内容,即使那不是真正的原因,这样做也很有道理。

3
ASP.NET MVC控制器释放哪些未托管的资源? - Robert Harvey
1
取决于它们做什么以及如何做。我不了解ASP.net MVC的内部情况,但我想其中涉及了大量文件句柄。控制器,可能还有其他包含DB连接的对象?不知道,也不关心。如果您持有任何IDisposable对象,提供Dispose方法是一种良好的习惯...并且对于持有您的对象的任何内容来调用它。 - cHao
那么为什么Dispose会清理我的TempData呢? - ErTR
@ErTR:就像我说的,我不了解ASP.net MVC的内部情况。但这听起来像是一个新问题,与Controller.Dispose(bool)没有太大关系(显然默认情况下它甚至什么都不做;它完全是为了被更有用的控制器覆盖而存在)。看起来你可能正在尝试将TempData用于比它设计的更长寿的数据。 - cHao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接