二、Disposable 模式
1.在.NET种由于当对象变为不可访问后将自动调用Finalize方法,所以我们手动调用IDisposable接口的Dispose方法和对象终结器调用的方法极其类似,我们最好将他们放到一起来处理。
我们首先想到的是重写Finalize方法,如下:
protected override void Finalize()
{
Console.WritleLine("析构函数执行...");
}
当我们编译这段代码的时候,我们发现编译器会报如下的错误: 这是因为编译器彻底屏蔽了父类的Finalize方法,编译器提示我们如果要重写Finalize方法我们要提供一个析构函数来代替,下面我们就提供一个析构函数:
~TestClass() { Console.WriteLine("析构函数执行..."); }
实际上这个析构函数编译器会将其转变为如下代码:
protected override void Finalize()
{
try {
Console.WritleLine("析构函数执行...");
}
finally {
base.Finalize();
}
}
2.然后我们就可以将Dispose方法的调用和对象的终结器放在一起来处理,如下:
public class TestClass: IDisposable
{
~TestClass()
{
Dispose();
}
public void Dispose()
{ // 清理资源
}
}
3.上面实现方式实际上调用了Dispose方法和Finalize方法,这样就有可能导致做重复的清理工作,所以就有了下面经典Disposable 模式:
private bool _isDisposed = false;
public void Dispose()
{
Dispose(true);
GC.SupressFinalize(this);
}
protected void Dispose(bool Diposing)
{
if(!_isDisposed)
{
if(Disposing)
{
//清理托管资源
}
//清理非托管资源
}
_isDisposed=true;
}
~TestClass()
{
Dispose(false);
}
3.1. SupressFinalize方法以防止垃圾回收器对不需要终止的对象调用 Object.Finalize()。
3.2. 使用IDisposable.Dispose 方法,用户可以在可将对象作为垃圾回收之前随时释放资源。如果调用了 IDisposable.Dispose方法,此方法会释放对象的资源。这样,就没有必要进行终止。IDisposable.Dispose 应调用 GC.SuppressFinalize 以使垃圾回收器不调用对象的终结器。
3.3.我们不希望Dispose(bool Diposing)方法被外部调用,所以他的访问级别为protected 。如果Diposing为true则释放托管资源和非托管资源,如果 Diposing等于false则该方法已由运行库从终结器内部调用,并且只能释放非托管资源。










