.NET 内存管理与垃圾回收:实现IDisposable接口和析构函数
.NET 类所使用的释放未托管资源的两种方式:
1、
利用析构函数,此方法有很多问题
2、
实现IDisposable接口,但需要确保执行Dispose()方法
最好的情况是执行这两种机制,获得这两种机制的有点,克服其缺点。假定大多数程序员都能正确调用Dispose()方法,同时把析构函数做为一种安全机制,确保在没有调用Dispose()的情况下也能释放掉资源。
Public class Resourceholder:IDisposable
{
Private bool isDisposed=false;
Public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
Protected virtual void Dispose(bool disposing)
{
If(!isDisposed)
{
If(disposing)
{
//通过调用托管对象的Dispose()方法释放托管对象
}
//释放未托管对象的代码
//比如关闭数据库的连接,关闭文件句柄等
}
isDisposed=true;
}
~ResourceHolder()
{
Dispose(false);
}
//其它的方法
}
Dispose()有一个protected的重载方法,带有一个bool类型的参数,这才是真正完成清理资源工作的方法,Dispose(bool)由析构函数个IDisposable.Dispose()调用。
传递给Dispose(bool)的参数表示Dispose(bool)是由析构函数调用(参数为false)还是由Dispose()调用(参数为true),并且Dispose(bool)不应该由其他方法调用。其原因是:
1、 如果客户调用了Dispose()方法,那么所有托管的和未托管的对象都会被清理
2、 如果没有调用Dispose()方法,析构函数迟早会被调用,该类所使用的资源仍然会被释放。
IsDisposed成员变量表示对象是否被删除。
最后IDisposeable.Dispose()包含一个对System.GC.SuppressFinalize()的调用,SuppressFinalize()方法告诉垃圾回收器有一个类不再需要调用析构函数,因为Dispose()已经完成了所有资源的回收,调用SuppressFinalize()就意味着GC认为这个对象没有析构函数