使用IDisposable与C#中的析构函数有什么区别?
我什么时候在类上实现IDispose而不是析构函数? 我读了这篇文章 ,但我仍然没有理解这一点。
我的假设是,如果我在一个对象上实现IDispose,我可以显式地“销毁”它,而不是等待垃圾收集器去做。 它是否正确?
这是否意味着我应该总是明确地调用一个对象上的Dispose? 这是什么常见的例子?
终结器(又名析构函数)是垃圾回收(GC)的一部分 – 当(或者甚至)发生这种情况时,它是不确定的,因为GC主要是由于内存压力(即需要更多空间)而发生的。 终结器通常只用于清理非托pipe资源,因为pipe理资源将有自己的收集/处置。
因此, IDisposable
用于确定性清理对象,即现在。 它不收集对象的内存(仍属于GC) – 但是用于closures文件,数据库连接等。
有很多以前的话题:
- 确定性定稿
- 处理对象
- 使用块
- 资源
最后,请注意, IDisposable
对象也有一个终结器是很常见的; 在这种情况下, Dispose()
通常会调用GC.SuppressFinalize(this)
,这意味着GC不运行终结器 – 它只是抛出内存(更便宜)。 如果忘记Dispose()
对象,终结器仍然运行。
Finalize()
方法的作用是确保.NET对象在收集垃圾时可以清理非托pipe资源。 但是,应该尽快释放诸如数据库连接或文件处理程序等对象,而不是依靠垃圾收集。 为此,您应该实现IDisposable
接口,并在Dispose()
方法中释放资源。
唯一应该在C#析构函数中的是这一行:
Dispose(False);
而已。 在这个方法中,没有别的东西是应该的。
MSDN上有很好的描述:
这个接口的主要用途是释放非托pipe资源 。 当垃圾收集器不再使用时,垃圾回收器会自动释放分配给pipe理对象的内存 。 但是, 无法预测垃圾回收何时发生 。 此外,垃圾收集器不知道非托pipe资源 ,如窗口句柄或打开的文件和stream。
使用此接口的Dispose方法与垃圾收集器一起显式释放非托pipe资源。 对象的使用者可以在不再需要该对象时调用此方法。
你关于你是否总是叫Dispose
的问题通常是一个激烈的争论。 看到这个博客从.NET社区尊敬的个人有趣的观点。
就我个人而言,我认为杰弗里·里希特(Jeffrey Richter)所说的Dispose
不是强制性的立场是非常弱的。 他举了两个例子来certificate他的观点。
在第一个例子中,他说在Windows窗体控件上调用Dispose
在主streamscheme中是乏味和不必要的。 但是他没有提到Dispose
在这些主stream场景中实际上是由控制容器自动调用的。
在第二个例子中,他指出开发人员可能会错误地认为来自IAsyncResult.WaitHandle
的实例应该积极处理,而不会意识到该属性会懒惰地初始化等待句柄,从而导致不必要的性能损失。 但是,这个例子的问题在于, IAsyncResult
本身并不遵循微软自己发布的处理IDisposable
对象的指导原则。 这就是说,如果一个类持有一个IDisposable
types的引用,那么该类本身应该实现IDisposable
。 如果IAsyncResult
遵循这个规则,那么它自己的Dispose
方法可以决定哪个组成成员需要处理。
所以除非有人提出一个更有说服力的论点,否则我会留在“一直以来都会被称为”Dispose“阵营的阵营中,这个阵营的理解是会出现一些主要是由于糟糕的deviseselect而出现的边缘案例。
这真的很简单。 我知道已经回答,但我会再试一次,但会尽量保持简单。
通常不应该使用析构函数。 它只运行.net希望它运行。 它只会在垃圾回收循环之后运行。 它可能永远不会在应用程序的生命周期中运行。 出于这个原因,你不应该把任何代码放在必须运行的析构函数中。 在运行时,也不能依赖类中的任何现有对象来存在(它们可能已经按照析构函数运行的顺序进行了清理)。
每当有一个对象创build需要清理的资源(即文件和graphics句柄)时,都应该使用IDisposible。 事实上,许多人认为,由于上面列出的原因,你放入析构函数的任何东西都应该放在IDisposable中。
大多数类会在finalizer被执行时调用dispose,但这只是作为一个安全的守卫,绝不应该被依赖。 你应该明确地处置任何实现IDisposable的东西,当你完成它。 如果你实现了IDisposable,你应该在终结器中调用dispose。 有关示例,请参阅http://msdn.microsoft.com/en-us/library/system.idisposable.aspx 。
这是另外一个很好的文章,它清除了一些围绕IDisposable,GC和处置的薄雾。
克里斯里昂WebLog解密处置