欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#中的IDisposable模式用法詳解

 更新時間:2014年09月06日 12:02:26   投稿:shichen2014  
這篇文章主要介紹了C#中的IDisposable模式用法,講述了垃圾資源回收機制的實現(xiàn),并對比分析了Dispose()方法、~DisposableClass()析構(gòu)函數(shù)、虛方法Dispose(bool disposing)的原理,需要的朋友可以參考下

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

首先,對于垃圾回收而言,在C#中,托管資源的垃圾回收是通過CLR的Garbage Collection來實現(xiàn)的,Garbage Collection會調(diào)用堆棧上對象的析構(gòu)函數(shù)完成對象的釋放工作;而對于一些非托管資源,比如數(shù)據(jù)庫鏈接對象等,需要實現(xiàn)IDisposable接口進行手動的垃圾回收。那么什么時候使用Idisposable接口,以及如何使用呢?

先來參考一下如下代碼:

public interface IDisposable
{
  void Dispose();
}
public class DisposablClass : IDisposable
{
  //是否回收完畢
  bool _disposed;
  public void Dispose()
  {
    Dispose(true);
    GC.SuppressFinalize(this);
  }
  ~DisposableClass()
  {
    Dispose(false);
  }
  
  //這里的參數(shù)表示示是否需要釋放那些實現(xiàn)IDisposable接口的托管對象
  protected virtual void Dispose(bool disposing)
  {
    if(_disposed) return; //如果已經(jīng)被回收,就中斷執(zhí)行
    if(disposing)
    {
      //TODO:釋放那些實現(xiàn)IDisposable接口的托管對象
    }
    //TODO:釋放非托管資源,設(shè)置對象為null
    _disposed = true;
  }
}

Dispose()方法

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

~DisposableClass(),析構(gòu)函數(shù)

當托管堆上的對象沒有被其它對象引用,GC會在回收對象之前,調(diào)用對象的析構(gòu)函數(shù)。這里的~DisposableClass()析構(gòu)函數(shù)的意義在于告訴GC你可以回收我,Dispose(false)表示在GC回收的時候,就不需要手動回收了。

虛方法Dispose(bool disposing)

通過此方法,所有的托管和非托管資源都能被回收。參數(shù)disposing表示是否需要釋放那些實現(xiàn)IDisposable接口的托管對象。

如果disposings設(shè)置為true,就表示DisposablClass類依賴某些實現(xiàn)了IDisposable接口的托管對象,可以通過這里的Dispose(bool disposing)方法調(diào)用這些托管對象的Dispose()方法進行回收。

如果disposings設(shè)置為false,就表示DisposableClass類依賴某些沒有實現(xiàn)IDisposable的非托管資源,那就把這些非托管資源對象設(shè)置為null,等待GC調(diào)用DisposableClass類的析構(gòu)函數(shù),把這些非托管資源進行回收。

另外,以上把Dispose(bool disposing)方法設(shè)置為protected virtual的原因是希望有子類可以一起參與到垃圾回收邏輯的設(shè)計,而且還不會影響到基類。比如有這樣的一個子類:

public class SubDisposableClass : DiposableClass
{
  private bool _disposed; //表示是否已經(jīng)被回收
  protected override void Dispose(bool disposing)
  {
    if(!_disposed) //如果還沒有被回收
    {
      if(disposiing) //如果需要回收一些托管資源
      {
        //TODO:回收托管資源,調(diào)用IDisposable的Dispose()方法就可以
      }
      //TODO:回收非托管資源,把之設(shè)置為null,等待CLR調(diào)用析構(gòu)函數(shù)的時候回收
      _disposed = true;
    }
    base.Dispose(disposing);//再調(diào)用父類的垃圾回收邏輯
  }
}

在.NET 2.0之前,如果一個對象的析構(gòu)函數(shù)拋出異常,這個異常會被CLR忽略。但.NET 2.0以后,如果析構(gòu)函數(shù)拋出異常就會導致應(yīng)用程序的崩潰。所以,保證析構(gòu)函數(shù)不拋異常變得非常重要。

還有,Dispose()方法允許拋出異常嗎?答案是否定的。如果Dispose()方法有拋出異常的可能,那就需要使用try/catch來手動捕獲。以下是考慮Dispose()方法有異常可能的寫法:

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

總結(jié):當我們自定義的類及其業(yè)務(wù)邏輯中引用某些托管和非托管資源,就需要實現(xiàn)IDisposable接口,實現(xiàn)對這些資源對象的垃圾回收。

希望本文所述對大家實現(xiàn)高效率的C#程序設(shè)計能夠有所幫助。

相關(guān)文章

  • C#實現(xiàn)3D效果完整實例

    C#實現(xiàn)3D效果完整實例

    這篇文章主要介紹了C#實現(xiàn)3D效果的方法,結(jié)合完整實例形式分析了C#實現(xiàn)文字3D顯示效果的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2016-08-08
  • C#中DataGridView常用操作實例小結(jié)

    C#中DataGridView常用操作實例小結(jié)

    這篇文章主要介紹了C#中DataGridView常用操作,以實例形式總結(jié)了DataGridView綁定下拉列表、設(shè)置默認值、判斷復選框是否選中等技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-09-09
  • C#迭代器方法介紹

    C#迭代器方法介紹

    這篇文章主要介紹了C#迭代器方法,可以使用foreach循環(huán)語句進行的迭代的方法,稱為可迭代方法,或者迭代器方法,方法操作,想了解更多內(nèi)容得小伙伴可以學習下面文章內(nèi)容,希望給你的學習帶來幫助
    2022-03-03
  • C#實現(xiàn)chart控件動態(tài)曲線繪制

    C#實現(xiàn)chart控件動態(tài)曲線繪制

    這篇文章主要為大家詳細介紹了C#實現(xiàn)chart控件動態(tài)曲線繪制,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C# WinForm程序處理后臺繁忙導致前臺控件假死現(xiàn)象解決方法

    C# WinForm程序處理后臺繁忙導致前臺控件假死現(xiàn)象解決方法

    這篇文章主要介紹了C# WinForm程序處理后臺繁忙導致前臺控件假死現(xiàn)象解決方法,本文通過Application.DoEvents()解決這個問題,并講解了Application.DoEvents()的作用,需要的朋友可以參考下
    2015-06-06
  • c#代碼生成URL地址的示例

    c#代碼生成URL地址的示例

    這篇文章主要介紹了c#代碼生成URL地址的方法,幫助大家更好的理解和學習使用c#,感興趣的朋友可以了解下
    2021-04-04
  • 利用lambda表達式樹優(yōu)化反射詳解

    利用lambda表達式樹優(yōu)化反射詳解

    這篇文章主要給大家介紹了關(guān)于如何利用lambda表達式樹優(yōu)化反射的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-12-12
  • C#實現(xiàn)動態(tài)加載dll的方法

    C#實現(xiàn)動態(tài)加載dll的方法

    這篇文章主要介紹了C#實現(xiàn)動態(tài)加載dll的方法,涉及針對動態(tài)鏈接庫的靈活操作技巧,具有一定的參考借鑒價值,需要的朋友可以參考下
    2014-12-12
  • 淺談C#中[]的幾種用法

    淺談C#中[]的幾種用法

    本文主要介紹了淺談C#中[]的幾種用法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-01-01
  • 基于WPF實現(xiàn)視頻封面查看器

    基于WPF實現(xiàn)視頻封面查看器

    這篇文章主要為大家詳細介紹了WPF如何實現(xiàn)視頻封面查看器,文中的示例代碼講解詳細,對我們學習或工作有一定幫助,感興趣的小伙伴可以了解一下
    2022-11-11

最新評論