什么情况下我应该在类上实现IDispose而不是析构函数?我阅读了这篇文章,但我仍然没有理解重点。
我的假设是,如果我在对象上实现了IDispose,那么我可以显式地“销毁”它,而不是等待垃圾回收器来处理。这个假设正确吗?
这是否意味着我应该总是显式调用对象的Dispose方法?有哪些常见的例子?
什么情况下我应该在类上实现IDispose而不是析构函数?我阅读了这篇文章,但我仍然没有理解重点。
我的假设是,如果我在对象上实现了IDispose,那么我可以显式地“销毁”它,而不是等待垃圾回收器来处理。这个假设正确吗?
这是否意味着我应该总是显式调用对象的Dispose方法?有哪些常见的例子?
Finalize()
方法的作用是确保一个.NET对象可以在垃圾回收时清理非托管资源。但是,例如数据库连接或文件处理程序等对象应该尽快释放,而不是依赖于垃圾回收。为此,您应该实现 IDisposable
接口,并在 Dispose()
方法中释放资源。
.Dispose()
。不能明确假设它会被调用。 - Enigmativity在MSDN上有一个非常好的描述:
这个接口的主要用途是释放非托管资源。当不再使用托管对象时,垃圾收集器会自动释放分配给该对象的内存。然而,无法预测垃圾回收何时发生。此外,垃圾收集器没有关于非托管资源(如窗口句柄或打开的文件和流)的知识。
使用此接口的Dispose方法与垃圾收集器一起显式释放非托管资源。当不再需要对象时,其使用者可以调用此方法。
Dispose(False);
就是这样。该方法中不应该有其他任何东西。
Dispose
的问题,通常会引起激烈的争论。请参考.NET社区中备受尊敬的人士在此博客中提供的有趣观点。Dispose
不是必须的立场非常薄弱。他举了两个例子来证明自己的观点。Dispose
在主流情况下是繁琐且不必要的。然而,他没有提到在这些主流情况下,控件容器实际上会自动调用Dispose
。IAsyncResult.WaitHandle
返回的实例需要被积极地释放,而没有意识到该属性惰性初始化等待句柄,导致不必要的性能损失。但是,这个例子的问题在于IAsyncResult
本身并没有遵循Microsoft对处理IDisposable
对象的公布指南。也就是说,如果一个类持有对IDisposable
类型的引用,那么该类本身应该实现IDisposable
。如果IAsyncResult
遵循这个规则,它自己的Dispose
方法就可以决定哪些成员需要释放。这其实很简单。我知道已经有答案了,但我会尽可能地保持简单。
析构函数通常不应该被使用。它只在 .net 想要运行时才会运行。它只会在垃圾回收周期之后运行。在您的应用程序生命周期中,它可能永远不会实际运行。因此,您不应该在析构函数中放置任何“必须”运行的代码。当它运行时,您也不能依赖于类中的任何现有对象存在(它们可能已被清理,因为析构函数运行的顺序不是保证的)。
每当您拥有一个创建需要清理的资源的对象时(例如文件和图形句柄),都应该使用 IDisposible。事实上,由于上述原因,许多人认为任何放在析构函数中的内容都应该放在 IDisposable 中。
大多数类将在执行终结器时调用 dispose,但这仅作为一种安全措施存在,不应该依赖于它。当您完成使用实现 IDisposable 的任何内容时,应显式地调用 dispose。如果您实现了 IDisposable,则应在终结器中调用 dispose。请参见 http://msdn.microsoft.com/en-us/library/system.idisposable.aspx 以获取示例。
当你亲眼目睹而非在脑海中想象时,像垃圾回收(GC)这样的概念会更容易理解。我制作了一个关于垃圾回收器的视频以更实践的方式回答这些问题。你可以从第10个问题开始观看,那里我开始谈论Dispose模式。