2020-07-21 Finalize和Dispose

Finalize和Dispose都是用来释放资源的。

Finalize也就是析构函数,是由gc来决定的,等到gc执行的时候才会去调用,而Dispose一般是我们主动去调用的,在c#里面,当我们使用using括起来的代码块,会在结束之后主动调用Dispose。比如:

using(MyClass my=new MyClass())
{

}

这段代码在执行完毕之后就会主动调用MyClass 的Dispose方法。

解释一下为什么我们经常会有一个protect类型的Dispose方法,参数是boo类型,形如
protect Dispose(bool disposing)
引用一段话:
只有一个Dispose()不可以. 为什么呢?因为如果只有一个Dispose()而没有Dispose(bool disposing)方法.那么在处理实现非托管资源释放的代码中无法判断该方法是客户调用的还是垃圾回收器通过Finalize调用的.无法实现 判断如果是客户手动调用,那么就不希望垃圾回收器再调用Finalize()(调用GC.SupperFinalize方法).另一个可能的原因(:我们知道如果是垃圾回收器通过Finalize调用的,那么在释放代码中我们可能还会引用其他一些托管对象,而此时这些托管对象可能已经被垃圾回收了, 这样会导致无法预知的执行结果(千万不要在Finalize中引用其他的托管对象).

还有一个好处,对外只提供Dispose方法,这样就不会错误的调用Dispose(false)了。

public class MyClass:IDisposable
{
    ~MyClass()
    {
      Dispose(false);
    }
    protected virtual void Dispose(bool disposing)
   {     
         // 那么这个方法是被客户直接调用的,那么托管的,和非托管的资源都可以释放
         if(disposing)
         {
            // 释放 托管资源
           
         }        
        
         //释放非托管资源
                        
         // 那么这个方法是被客户直接调用的,告诉垃圾回收器从Finalization队列中清除自己,从而阻止垃圾回                收器调用Finalize方法.        
         if(disposing) 
           GC.SuppressFinalize(this);            
   }
    //主动调用的dispose 
    public void Dispose()
   {
      Dispose(true);     
   }

}

你可能感兴趣的:(2020-07-21 Finalize和Dispose)