类型的 Dispose 方法应该释放它拥有的所有资源。它还应该通过调用其父类型的 Dispose 方法释放其基类型拥有的所有资源。
Dispose 方法应该为它处置的对象调用 GC.SuppressFinalize 方法 。如果对象当前在终止队列中,GC.SuppressFinalize 防止其 Finalize 方法被调用。执行 Finalize 方法会大大减损性能。如果您的 Dispose 方法已经完成了清理对象的工作,那么垃圾回收器就不必调用对象的 Finalize 方法了。
Dispose(bool disposing) 以两种截然不同的方案执行。如果“处置”等于“真”,则该方法已由用户的代码直接调用或间接调用,并且可处置托管资源和非托管资源。如果“处置”等于“假”,则该方法已由运行库从终结器内部调用,并且只能处置非托管资源。
基类提供的 Finalize 方法或析构函数在未能调用 Dispose 的情况下充当防护措施。Finalize 方法调用带有参数的 Dispose 方法,同时传递“假”。
public class BaseResource: IDisposable
{
// 非托管资源
private IntPtr handle;
// 托管资源
private Component Components;
// Track whether Dispose has been called.
private bool disposed = false;
public BaseResource()
{....}
public void Dispose()
{
Dispose(true);
//因为前面Dispose(true)已经将所有资源全部释放,所以不学要再调用finalize,以节省资源。
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!this.disposed)
{
if(disposing)
{
// 释放托管资源
Components.Dispose();
}// 释放非托管资源
CloseHandle(handle);
handle = IntPtr.Zero;
}
disposed = true;
}
// 这个析构函数在Dispose没有被调用时 才被调用
~BaseResource()
{
Dispose(false);
}
// 使你的Dispose方法被多次调用,但是对象如果已经disposed则将从此处抛出异常
// 任何时候你要用对象去做任何事情你都应该检查该对象是否已经disposed
public void DoSomething()
{
if(this.disposed)
{
throw new ObjectDisposedException();
}
}
}
public class MyResourceWrapper: BaseResource
{
// 托管资源
private ManagedResource addedManaged;
// 非托管资源
private NativeResource addedNative;
private bool disposed = false;
public MyResourceWrapper()
{.... }
protected override void Dispose(bool disposing)
{
if(!this.disposed)
{
try
{
if(disposing)
{
addedManaged.Dispose();
}
CloseHandle(addedNative);
this.disposed = true;
}
finally
{//调用父类的dispose函数
base.Dispose(disposing);
}
}
}
}