.net 题目笔记:Finalize 和 Dispose的异同
用人话来说:两者都是用于回收释放资源的函数。
Finalize 是CLR的机制。从Object开始就带有Finalize 的虚方法方法,当对象完成其生命周期,GC就通过调用Finalize释放其资源。尤其是非托管资源,开发者就必须在Finalize方法中处理 非托管资源的释放。但GC不确定性,所以不一定能及时释放非托管资源.可能会导致性能的降低.
Dispose 是 IDisposable 的一个 方法,不是CRL的机制。目的是提供调用,让使用者收统调用释放的机会,不需要再等待GC。实际上实现Dispose,就是将Finalize里释放资源的指令迁移到 Dispose 里面,保证了释放资源的及时性。
另外 Dispose 包括 Dispose(bool disposing) 和 Dispose() 。两种写法就是为了避免带来混淆。其中 Dispose(bool disposing) 是函数的真正实现,通过 bool disposing参数 识别调用来源究竟是 使用者还是CLR。因为使用者一般都早于CLR,所以通过 Dispose(false)避免了反复释放已经释放的资源。而使用者 直接调用 Dispose就好了。
见下方范例代码。参考来源
public class BaseResource: IDisposable { //前面我们说了析构函数实际上是重写了 System.Object 中的虚方法 Finalize, //默认情况下,一个类是没有析构函数的,也就是说,对象被垃圾回收时不会被调用Finalize方法 ~BaseResource() { // 为了保持代码的可读性性和可维护性,千万不要在这里写释放非托管资源的代码 // 必须以Dispose(false)方式调用,以false告诉Dispose(bool disposing)函数是从垃圾回收器在调用Finalize时调用的 Dispose(false); } // 无法被客户直接调用 // 如果 disposing 是 true, 那么这个方法是被客户直接调用的,那么托管的,和非托管的资源都可以释放 // 如果 disposing 是 false, 那么函数是从垃圾回收器在调用Finalize时调用的,此时不应当引用其他托管对象所以,只能释放非托管资源 protected virtual void Dispose(bool disposing) { // 那么这个方法是被客户直接调用的,那么托管的,和非托管的资源都可以释放 if(disposing) { OtherManagedObject.Dispose(); // 释放 托管资源 } DoUnManagedObjectDispose(); //释放非托管资源 // 那么这个方法是被客户直接调用的,告诉垃圾回收器从Finalization队列中清除自己,从而阻止垃圾回收器调用Finalize方法. if(disposing) GC.SuppressFinalize(this); } public void Dispose() {//可以被客户直接调用 Dispose(true); //必须以Dispose(true)方式调用,以true告诉Dispose(bool disposing)函数是被客户直接调用的 } }
这里就是 通过Dispose替代了 Finalize的实现,实现了更高效的资源释放。
浙公网安备 33010602011771号