C#中標準的IDispose模式代碼詳解

在本篇文章中小編給大家分享的是關於C#中標準的IDispose模式的實例用法相關內容,有需要的朋友們測試下。

C#實現IDispose接口

.net的GC機制有兩個問題:首先GC並不能釋放所有資源,它更不能釋放非託管資源。其次,GC也不是實時的,所有GC存在不確定性。

爲了解決這個問題donet提供了析構函數

public class TestClass : System.IDisposable
{
  //供程序員顯式調用的Dispose方法
  public void Dispose()
  {
    //調用帶參數的Dispose方法,釋放託管和非託管資源
    Dispose(true);
    //手動調用了Dispose釋放資源,那麼析構函數就是不必要的了,這裏阻止GC調用析構函數
    System.GC.SuppressFinalize(this);
  }

  //protected的Dispose方法,保證不會被外部調用。
  //傳入bool值disposing以確定是否釋放託管資源
  protected void Dispose(bool disposing)
  {
    if (disposing)
    {
      ///TODO:在這裏加入清理"託管資源"的代碼,應該是xxx.Dispose();
    }
    ///TODO:在這裏加入清理"非託管資源"的代碼
  }

  //供GC調用的析構函數
  ~TestClass()
  {
    Dispose(false);//釋放非託管資源
  }
}

而即使我們忘記了在合適的時候調用Dispose,GC也會在釋放對象的時候幫我們清理非託管資源的。GC所充當的角色只是一種保障手段,它應該充當這種角色,我們不能過分依賴它。實際上,在較大的模塊退出時我們還應該及時地手動調用GC.Collect進行垃圾回收。

爲什麼實現IDisposable接口的類的對象,因爲.net CLR是採用GC(垃圾回收器)機制管理內存,不想C++語言那樣,能保證對象的析構函數在作用域結束時被總是被自動調用,有時如果程序運行的過程中一直沒有滿足啓動GC的條件,則可能GC一次也沒啓動。 這樣,如果一個類需要佔用重要資源,就應該實現IDisposable接口,或者使用另一種簡捷的方式:使用Using,如:

Using(MyClass myObj = new MyClass())

{ ... }

對於沒有實現IDisposable接口的,也就沒什麼Dispose方法,但他們的Finalize同樣不能保證被調用。

Using(MyClass myObj = new MyClass())

{ ... }

是一種好方法,但是隻有MyClass實現了IDisposable接口才能這樣寫.

IDispose模式在C++中用的很多,用來清理資源,而在C#裏,資源分爲託管和非託管兩種,託管資源是由C#的CLR幫助我們清理的,它是通過調用對象的析構函數完成的對象釋放工作,而對於非託管系統來說,則需要我們自己來釋放,例如數據庫連接對象,這就需要我們手動去調用它的Dispose()方法來實現對象它的釋放,事實上,Dispose()內容到底做了什麼事,我們並不清楚,當然這就是面向對象,它不希望你關係實現的細節,呵!

對於我們開發人員來說,在瞭解它怎麼用之後,總會對它如何實現的產生興趣,下面,我將把C#裏實現IDispose模式的代碼展現出來,大家一起來學習一下,事實上,它的使用場合也很多的,當我們手動對網站,數據庫作封裝時,都會用的到,下面看一下代碼:

 /// <summary>
  /// 實現IDisposable,對非託管系統進行資源回收
  /// </summary>
  public class IDisplosePattern : IDisposable
  {
    public void Dispose()
    {
      this.Dispose(true);////釋放託管資源
      GC.SuppressFinalize(this);//請求系統不要調用指定對象的終結器. //該方法在對象頭中設置一個位,系統在調用終結器時將檢查這個位
    }

    protected virtual void Dispose(bool disposing)
    {
      if (!_isDisposed)//_isDisposed爲false表示沒有進行手動dispose
      {
        if (disposing)
        {
          //清理託管資源
        }
        //清理非託管資源
      }
      _isDisposed = true;
    }

    private bool _isDisposed;

    ~IDisplosePattern()
    {
      this.Dispose(false);//釋放非託管資源,託管資源由終極器自己完成了
    }
  }

通過上面的代碼,我們知道了,對於託管系統(C#的CLR爲我們管理的),直接通過~IDisplosePattern()方法進行釋放,而~IDisplosePattern()這個方法何時被調用,我們是不知道的,因爲它是由CLR幫助我們調用的,而我們手動進行dispose方法時,它會調用dispose(true)這個重載方法,它會幫助我們清理託管和非託管資源,如圖:

以上就是本次介紹的全部知識點內容,感謝大家的學習和對神馬文庫的支持。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章