.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认为这个对象没有析构函数

posted @ 2011-01-14 13:48  哭过的天空  阅读(2015)  评论(3编辑  收藏  举报