偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

淺談C#中標(biāo)準(zhǔn)Dispose模式的實(shí)現(xiàn)

開(kāi)發(fā) 后端
C#程序中的Dispose方法,一旦被調(diào)用了該方法的對(duì)象,雖然還沒(méi)有垃圾回收,但實(shí)際上已經(jīng)不能再使用了。所以使用上要仔細(xì)考慮細(xì)節(jié)。

需要明確一下C#程序(或者說(shuō).NET)中的資源。簡(jiǎn)單的說(shuō)來(lái),C#中的每一個(gè)類型都代表一種資源,而資源又分為兩類:

托管資源:由CLR管理分配和釋放的資源,即由CLR里new出來(lái)的對(duì)象;

非托管資源:不受CLR管理的對(duì)象,windows內(nèi)核對(duì)象,如文件、數(shù)據(jù)庫(kù)連接、套接字、COM對(duì)象等;

毫無(wú)例外地,如果我們的類型使用到了非托管資源,或者需要顯式釋放的托管資源,那么,就需要讓類型繼承接口IDisposable。這相當(dāng)于是告訴調(diào)用者,該類型是需要顯式釋放資源的,你需要調(diào)用我的Dispose方法。

不過(guò),這一切并不這么簡(jiǎn)單,一個(gè)標(biāo)準(zhǔn)的繼承了IDisposable接口的類型應(yīng)該像下面這樣去實(shí)現(xiàn)。這種實(shí)現(xiàn)我們稱之為Dispose模式:

  1. public class SampleClass : IDisposable    
  2.   {        
  3.   //演示創(chuàng)建一個(gè)非托管資源          
  4. private IntPtr nativeResource = Marshal.AllocHGlobal(100);          
  5. //演示創(chuàng)建一個(gè)托管資源          
  6. private AnotherResource managedResource = new AnotherResource();          
  7. private bool disposed = false;         
  8.  /// <summary>          
  9. /// 實(shí)現(xiàn)IDisposable中的Dispose方法         
  10.  /// </summary>          
  11. public void Dispose()       
  12.    {             
  13.  //必須為true             
  14.  Dispose(true);             
  15.  //通知垃圾回收機(jī)制不再調(diào)用終結(jié)器(析構(gòu)器)         
  16.    GC.SuppressFinalize(this);       
  17.    }         
  18.  /// <summary>         
  19.  /// 不是必要的,提供一個(gè)Close方法僅僅是為了更符合其他語(yǔ)言(如C++)的規(guī)范          
  20. /// </summary>          
  21. public void Close()        
  22.   {            
  23.   Dispose();       
  24.    }        
  25.   /// <summary>       
  26.    /// 必須,以備程序員忘記了顯式調(diào)用Dispose方法      
  27.     /// </summary>         
  28.  ~SampleClass()        
  29.   {          
  30.     //必須為false           
  31.    Dispose(false);      
  32.     }          
  33. /// <summary>          
  34. /// 非密封類修飾用protected virtual        
  35.   /// 密封類修飾用private        
  36.   /// </summary>         
  37.  /// <param name="disposing"></param>    
  38.       protected virtual void Dispose(bool disposing)          
  39. {             
  40.  if (disposed)           
  41.    {               
  42.    return;          
  43.     }          
  44.     if (disposing)         
  45.      {             
  46.      // 清理托管資源              
  47.     if (managedResource != null)              
  48.   {                  
  49.     managedResource.Dispose();                
  50.     managedResource = null;              
  51.     }       
  52.        }            
  53.   // 清理非托管資源           
  54.    if (nativeResource != IntPtr.Zero)         
  55.    {              
  56.     Marshal.FreeHGlobal(nativeResource);        
  57.         nativeResource = IntPtr.Zero;        
  58.       }             
  59.  //讓類型知道自己已經(jīng)被釋放           
  60.    disposed = true;    
  61.       }     
  62.      public void SamplePublicMethod()       
  63.    {             
  64.  if (disposed)         
  65.      {               
  66.    throw new ObjectDisposedException("SampleClass""SampleClass is disposed");       
  67.        }        
  68.       //省略        
  69.   }    } 

在Dispose模式中,幾乎每一行都有特殊的含義。

在標(biāo)準(zhǔn)的Dispose模式中,我們注意到一個(gè)以~開(kāi)頭的方法:

  1. /// <summary>       
  2.   /// 必須,以備程序員忘記了顯式調(diào)用Dispose方法      
  3.    /// </summary>        
  4.  ~SampleClass()       
  5.   {             
  6. //必須為false           
  7.   Dispose(false);     
  8.     }  

這個(gè)方法叫做類型的終結(jié)器。提供終結(jié)器的全部意義在于:我們不能奢望類型的調(diào)用者肯定會(huì)主動(dòng)調(diào)用Dispose方法,基于終結(jié)器會(huì)被垃圾回收器調(diào)用這個(gè)特點(diǎn),終結(jié)器被用做資源釋放的補(bǔ)救措施。

一個(gè)類型的Dispose方法應(yīng)該允許被多次調(diào)用而不拋異常。鑒于這個(gè)原因,類型內(nèi)部維護(hù)了一個(gè)私有的布爾型變量disposed:

  1. private bool disposed = false

在實(shí)際處理代碼清理的方法中,加入了如下的判斷語(yǔ)句:

  1. if (disposed)      
  2.         {               
  3.    return;          
  4.     }             
  5.  //省略清理部分的代碼,并在方法的***為disposed賦值為true              
  6. disposed = true

這意味著類型如果被清理過(guò)一次,則清理工作將不再進(jìn)行。

應(yīng)該注意到:在標(biāo)準(zhǔn)的Dispose模式中,真正實(shí)現(xiàn)IDisposable接口的Dispose方法,并沒(méi)有實(shí)際的清理工作,它實(shí)際調(diào)用的是下面這個(gè)帶布爾參數(shù)的受保護(hù)的虛方法:

  1.       /// <summary>       
  2.  /// 非密封類修飾用protected virtual        
  3. /// 密封類修飾用private       
  4.  /// </summary>        
  5. /// <param name="disposing"></param>       
  6.  protected virtual void Dispose(bool disposing)      
  7.   {            
  8. //省略代碼    
  9.     } 

之所以提供這樣一個(gè)受保護(hù)的虛方法,是為了考慮到這個(gè)類型會(huì)被其他類繼承的情況。如果類型存在一個(gè)子類,子類也許會(huì)實(shí)現(xiàn)自己的Dispose模式。受保護(hù)的虛方法用來(lái)提醒子類必須在實(shí)現(xiàn)自己的清理方法的時(shí)候注意到父類的清理工作,即子類需要在自己的釋放方法中調(diào)用base.Dispose方法。
還有,我們應(yīng)該已經(jīng)注意到了真正撰寫(xiě)資源釋放代碼的那個(gè)虛方法是帶有一個(gè)布爾參數(shù)的。之所以提供這個(gè)參數(shù),是因?yàn)槲覀冊(cè)谫Y源釋放時(shí)要區(qū)別對(duì)待托管資源和非托管資源。

在供調(diào)用者調(diào)用的顯式釋放資源的無(wú)參Dispose方法中,調(diào)用參數(shù)是true:

  1. public void Dispose()      
  2.     {            
  3.   //必須為true         
  4.      Dispose(true);        
  5.       //其他省略        
  6.   } 

這表明,這個(gè)時(shí)候代碼要同時(shí)處理托管資源和非托管資源。

在供垃圾回收器調(diào)用的隱式清理資源的終結(jié)器中,調(diào)用參數(shù)是false:

  1. ~SampleClass()        
  2.   {         
  3.      //必須為false         
  4.      Dispose(false);    
  5.       } 

這表明,隱式清理時(shí),只要處理非托管資源就可以了。

那么,為什么要區(qū)別對(duì)待托管資源和非托管資源。在認(rèn)真闡述這個(gè)問(wèn)題之前,我們需要首先弄明白:托管資源需要手動(dòng)清理嗎?不妨先將C#中的類型分為兩類,一類繼承了IDisposable接口,一類則沒(méi)有繼承。前者,我們暫時(shí)稱之為非普通類型,后者我們稱之為普通類型。非普通類型因?yàn)榘峭泄苜Y源,所以它需要繼承IDisposable接口,但是,這個(gè)包含非托管資源的類型本身,它是一個(gè)托管資源。所以說(shuō),托管資源需要手動(dòng)清理嗎?這個(gè)問(wèn)題的答案是:托管資源中的普通類型,不需要手動(dòng)清理,而非普通類型,是需要手動(dòng)清理的(即調(diào)用Dispose方法)。

Dispose模式設(shè)計(jì)的思路基于:如果調(diào)用者顯式調(diào)用了Dispose方法,那么類型就該按部就班為自己的所以資源全部釋放掉。如果調(diào)用者忘記調(diào)用Dispose方法,那么類型就假定自己的所有托管資源(哪怕是那些上段中闡述的非普通類型)全部交給垃圾回收器去回收,而不進(jìn)行手工清理。理解了這一點(diǎn),我們就理解了為什么Dispose方法中,虛方法傳入的參數(shù)是true,而終結(jié)器中,虛方法傳入的參數(shù)是true。 

注意:我們提到了需要及時(shí)釋放資源,卻并沒(méi)有進(jìn)一步細(xì)說(shuō)是否需要及時(shí)讓引用等于null這一點(diǎn)。有一些人認(rèn)為等于null可以幫助垃圾回收機(jī)制早點(diǎn)發(fā)現(xiàn)并標(biāo)識(shí)對(duì)象是垃圾。其他人則認(rèn)為這沒(méi)有任何幫助。下一篇我們?cè)偌?xì)說(shuō)這一點(diǎn)。

原文鏈接:http://www.cnblogs.com/luminji/archive/2011/03/29/1997812.html

【編輯推薦】

  1. C#取整函數(shù)實(shí)例應(yīng)用詳解
  2. C#單元測(cè)試的一個(gè)小故事
  3. C#單元測(cè)試使用的必要性的淺析
  4. C#單元測(cè)試概念及作用的淺析
  5. C#單元測(cè)試的運(yùn)行淺析



【責(zé)任編輯:彭凡 TEL:(010)68476606】

 

責(zé)任編輯:彭凡 來(lái)源: 博客園
相關(guān)推薦

2009-09-07 09:53:01

C# DisposeDispose方法

2009-09-07 09:36:29

C# DisposeDispose方法

2009-08-31 16:33:28

C#調(diào)用Dispose

2009-09-02 16:23:27

C# Singleto

2009-09-11 10:59:06

Effective C調(diào)用Dispose()

2009-08-04 09:22:26

C#工廠模式

2009-06-16 10:20:05

多繼承C#

2009-08-17 17:16:19

C#實(shí)現(xiàn)在線升級(jí)

2009-07-22 17:15:04

C#實(shí)現(xiàn)

2011-09-21 10:56:31

C#結(jié)構(gòu)

2009-08-20 18:30:33

C# ReaderWr

2010-01-27 16:33:07

C++中標(biāo)準(zhǔn)輸入

2009-09-17 17:13:54

C#數(shù)組

2009-08-14 10:51:43

2009-08-25 18:04:30

C#實(shí)現(xiàn)Singlet

2009-09-11 12:17:59

C#控件屬性

2009-08-07 11:26:53

C#數(shù)組結(jié)構(gòu)

2009-08-19 17:12:18

C# Connecti

2009-08-12 11:24:25

C# String對(duì)象

2009-08-31 09:37:09

C# Employee
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)