最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#中的IDisposable模式用法詳解

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

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

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

先來(lái)參考一下如下代碼:

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

Dispose()方法

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

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

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

虛方法Dispose(bool disposing)

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

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

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

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

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

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

還有,Dispose()方法允許拋出異常嗎?答案是否定的。如果Dispose()方法有拋出異常的可能,那就需要使用try/catch來(lái)手動(dòng)捕獲。以下是考慮Dispose()方法有異??赡艿膶?xiě)法:

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

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

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

相關(guān)文章

  • 深入理解C# abstract和virtual關(guān)鍵字

    深入理解C# abstract和virtual關(guān)鍵字

    深入理解C# abstract和virtual關(guān)鍵字,學(xué)習(xí)c#的朋友可以參考下。
    2011-06-06
  • C#實(shí)現(xiàn)人臉識(shí)別超簡(jiǎn)單方法舉例

    C#實(shí)現(xiàn)人臉識(shí)別超簡(jiǎn)單方法舉例

    這篇文章主要給大家介紹了關(guān)于C#實(shí)現(xiàn)人臉識(shí)別的相關(guān)資料,文中講解了在C#中使用EmguCV庫(kù)進(jìn)行人臉識(shí)別的簡(jiǎn)單示例,包括安裝EmguCV庫(kù)、準(zhǔn)備訓(xùn)練數(shù)據(jù)、編寫(xiě)代碼和運(yùn)行程序,需要的朋友可以參考下
    2024-11-11
  • C#異步編程幾點(diǎn)需要注意的地方

    C#異步編程幾點(diǎn)需要注意的地方

    這篇文章我們來(lái)討論下關(guān)于C#異步編程幾個(gè)不成文的建議,希望對(duì)你寫(xiě)出高性能的異步編程代碼有所幫助
    2020-05-05
  • 淺談C#中簡(jiǎn)單的異常引發(fā)與處理操作

    淺談C#中簡(jiǎn)單的異常引發(fā)與處理操作

    這篇文章主要介紹了C#中簡(jiǎn)單的異常引發(fā)與處理操作,講到了Exception類和try...catch及throw語(yǔ)句的基本使用,需要的朋友可以參考下
    2016-02-02
  • C#實(shí)現(xiàn)文件與Base64的相互轉(zhuǎn)換

    C#實(shí)現(xiàn)文件與Base64的相互轉(zhuǎn)換

    本文主要介紹了C#實(shí)現(xiàn)文件與Base64的相互轉(zhuǎn)換,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Unity 通過(guò)LineRenderer繪制兩點(diǎn)之間的直線操作

    Unity 通過(guò)LineRenderer繪制兩點(diǎn)之間的直線操作

    這篇文章主要介紹了Unity 通過(guò)LineRenderer繪制兩點(diǎn)之間的直線操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • C#排序算法之快速排序

    C#排序算法之快速排序

    下面給出的代碼是以數(shù)組最后一個(gè)元素作為參考元素,這僅是參考元素選取的方式之一。
    2010-09-09
  • C#中sleep和wait的區(qū)別分析

    C#中sleep和wait的區(qū)別分析

    這篇文章主要介紹了C#中sleep和wait的區(qū)別分析,有助于深入理解C#中線程的原理與使用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • Unity3D如何獲取時(shí)間戳或北京時(shí)間

    Unity3D如何獲取時(shí)間戳或北京時(shí)間

    這篇文章主要為大家詳細(xì)介紹了Unity3D獲取時(shí)間戳或北京時(shí)間的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • 關(guān)于Unity C# Mathf.Abs()取絕對(duì)值性能測(cè)試詳解

    關(guān)于Unity C# Mathf.Abs()取絕對(duì)值性能測(cè)試詳解

    這篇文章主要給大家介紹了關(guān)于Unity C# Mathf.Abs()取絕對(duì)值性能測(cè)試的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Unity C#具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04

最新評(píng)論

梓潼县| 星子县| 习水县| 临江市| 军事| 田林县| 岳普湖县| 舞阳县| 加查县| 许昌县| 当阳市| 惠来县| 临颍县| 苏尼特右旗| 姚安县| 双柏县| 女性| 阳高县| 疏附县| 射洪县| 明水县| 延川县| 株洲市| 南陵县| 开化县| 柳州市| 甘肃省| 太和县| 铜陵市| 广平县| 鹤庆县| 台州市| 望奎县| 洛宁县| 封丘县| 馆陶县| 留坝县| 平阳县| 虹口区| 安乡县| 即墨市|