C#中的IDisposable模式用法詳解

來源:互聯網
上載者:User

標籤:自訂格式   調用   隨機   base   影響   elf   ddd   border   對象   

本文執行個體講述了C#中IDisposable模式的用法,針對垃圾資源的回收進行了較為詳細的講解。分享給大家供大家參考之用。具體方法如下:

首先,對於記憶體回收而言,在C#中,託管資源的記憶體回收是通過CLR的Garbage Collection來實現的,Garbage Collection會呼叫堆疊上對象的解構函式完成對象的釋放工作;而對於一些非託管資源,比如資料庫連結化物件等,需要實現IDisposable介面進行手動的記憶體回收。那麼什麼時候使用Idisposable介面,以及如何使用呢?

先來參考一下如下代碼:

public interface IDisposable{  void Dispose();}public class DisposablClass : IDisposable{  //是否回收完畢  bool _disposed;  public void Dispose()  {    Dispose(true);    GC.SuppressFinalize(this);  }  ~DisposableClass()  {    Dispose(false);  }  //這裡的參數表示示是否需要釋放那些實現IDisposable介面的託管對象  protected virtual void Dispose(bool disposing)  {    if(_disposed) return; //如果已經被回收,就中斷執行    if(disposing)    {      //TODO:釋放那些實現IDisposable介面的託管對象    }    //TODO:釋放非託管資源,設定對象為null    _disposed = true;  }}


Dispose()方法

當需要回收非託管資源的DisposableClass類,就調用Dispoase()方法。而這個方法不會被CLR自動調用,需要手動調用。


~DisposableClass(),解構函式

當託管堆上的對象沒有被其它對象引用,GC會在回收對象之前,調用對象的解構函式。這裡的~DisposableClass()解構函式的意義在於告訴GC你可以回收我,Dispose(false)表示在GC回收的時候,就不需要手動回收了。


虛方法Dispose(bool disposing)

通過此方法,所有的託管和非託管資源都能被回收。參數disposing表示是否需要釋放那些實現IDisposable介面的託管對象。

如果disposings設定為true,就表示DisposablClass類依賴某些實現了IDisposable介面的託管對象,可以通過這裡的Dispose(bool disposing)方法調用這些託管對象的Dispose()方法進行回收。

如果disposings設定為false,就表示DisposableClass類依賴某些沒有實現IDisposable的非託管資源,那就把這些非託管資來源物件設定為null,等待GC調用DisposableClass類的解構函式,把這些非託管資源進行回收。

另外,以上

把Dispose(bool disposing)方法設定為protected virtual的原因是希望有子類可以一起參與到記憶體回收邏輯的設計,而且還不會影響到基類

。比如有這樣的一個子類:

public class SubDisposableClass : DiposableClass{  private bool _disposed; //表示是否已經被回收  protected override void Dispose(bool disposing)  {    if(!_disposed) //如果還沒有被回收    {      if(disposiing) //如果需要回收一些託管資源      {        //TODO:回收託管資源,調用IDisposable的Dispose()方法就可以      }      //TODO:回收非託管資源,把之設定為null,等待CLR調用解構函式的時候回收      _disposed = true;    }    base.Dispose(disposing);//再調用父類的記憶體回收邏輯  }}


在.NET 2.0之前,如果一個對象的解構函式拋出異常,這個異常會被CLR忽略。但.NET 2.0以後,如果解構函式拋出異常就會導致應用程式的崩潰。所以,保證解構函式不拋異常變得非常重要

還有,Dispose()方法允許拋出異常嗎?答案是否定的。

如果Dispose()方法有拋出異常的可能,那就需要使用try/catch來手動捕獲

。以下是考慮Dispose()方法有異常可能的寫法:

public class DisposableClass : IDisposable{  bool _disposed;  ......  protected virtual void Dispose(bool disposing)  {    if(_disposed) return;    if(disposing)    {      //TODO:調用託管資源的Dispose()方法進行記憶體回收    }    try    {      _channelFactory.Close(); //關閉的時候可能會有異常    }    catch(Exception ex)    {      _log.Warn(ex);//記錄日誌      try      {        _channelFactory.Abort();//丟棄的時候可能會有異常      }      catch(Exception cex)      {        _log.Warn(cex);//記錄日誌      }    }    _channelFactory = null;    _disposed = true;  }}


總結:


當我們自訂的類及其商務邏輯中引用某些託管和非託管資源,就需要實現IDisposable介面,實現對這些資來源物件的記憶體回收。

希望本文所述對大家實現高效率的C#程式設計能夠有所協助。

除聲明外, 跑步客文章均為原創,轉載請以連結形式標明本文地址
  C#中的IDisposable模式用法詳解

本文地址:  http://www.paobuke.com/develop/c-develop/pbk23539.html






相關內容C#自訂音樂播放器進度條C#使用winform簡單匯出Excel的方法基於C#實現簡單的隨機抽獎小程式詳解C#編程中.NET的弱事件模式
C# WebClient類用法執行個體C#中使用IFormattable實現自訂格式化字串輸出樣本C#編程實現向並口裝置發送指令、擷取並口裝置的狀態C#的回調機制淺析

C#中的IDisposable模式用法詳解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.