如何妥善使用Dispose()和析构函数

(1)首先要明白一个原则:资源在哪个类中被创建就应该在哪个类中清理。如果类中调用了其他基类中创建的资源,则应在基类中删除这些资源。然后看以下内容。  
  (2)析构函数:  
  析构函数是由垃圾回收器在清理对象时调用的。  
  因为.NET中的托管对象都是由垃圾回收器自动定期清理的,所以如果一个类中只有托管对象,则垃圾回收器在回收该对象时会同时一次性清理掉该类中创建的托管对象,此种情况下不要编写析构函数(情况A)。  
  如果一个类中创建使用了非托管资源(如数据库连接)(情况B),此时应该使用析构函数,但也只是作为忘记调用Dispose()函数的一种备份机制。换言之,此时,应该先掉用Dispose()函数来删除资源。  
  (3)Dispose()函数:  
  Dispose()函数由用户来调用。  
  在上面的情况A中,可以不调用Dispose()函数。但如果类中创建使用过一些较大的托管对象,最好尽快清除它们,此时可以在Dispose函数中删除它们,并由用户调用以尽快删除它们。  
   
  在情况B中,应该在Dispose()中删除非托管资源,并由用户调用Dispose()。此时,为防止垃圾回收器再次调用析构函数,应该在Dispose()中调用GC.SuppressFinalize(this)通知垃圾回收器,此对象已经不再需要执行析构函数以免重复执行。但如果用户忘记了调用Dispose(),则垃圾回收器仍然会执行析构函数,保证非托管资源会被清除。  
   
  以上对析构函数和Dispose()用法说明参看下面代码:  
   
  public   class   MyClass():IDisposable  
  {  
        private   StreamReader   sr;  
        private   int   connection;    
        ......  
        public   void   Dispose()  
        {  
              Dispose(true);  
              GC.SuppressFinally(this);  
          }  
           
          protected   virtual   void   Dispose(bool   disposing)  
          {  
                  if(disposing)  
                  {     //清理托管资源  
                        if(sr!=null)  
                        {  
                              sr.Close();  
                              sr=null;  
                          }  
                  }  
                //清理非托管对象  
                  CloseConnection();   //假设类中有这样一个函数用于清理connection这个非托管资源  
            }  
   
            ~MyClass()  
            {  
                  Dispose(false);//仅仅清理非托管资源,除此外不应编写其它代码。  
              }  
            .....  
  } 

ContractedBlock.gif ExpandedBlockStart.gif Code
public class test : IDisposable
{
    
//防止重复调用
    private bool _alreadyDisposed = false;
    
public void Dispose()
    {
        Dispose(
true);
        GC.SuppressFinalize(
this);
    }
    
protected virtual void Dispose(bool flage)
    {
        
if (_alreadyDisposed) return;
        
if (flage)
        {
            
//托管
        }
        
//非托管
        _alreadyDisposed = true;
    }
    
~test()
    {
        Dispose(
false);
    }


}
//子类代码
public class testExtend : test
{
    
//防止重复调用
    private bool _alreadyDisposed = false;
    
protected override void Dispose(bool flage)
    {
        
if (_alreadyDisposed) return;
        
if (flage)
        {
            
//托管
        }
        
//非托管
        base.Dispose(flage);
        _alreadyDisposed 
= true;
    }
}

转载于:https://www.cnblogs.com/deymmtd/archive/2009/01/12/1374515.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值