程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#中的IDisposable形式用法詳解

C#中的IDisposable形式用法詳解

編輯:C#入門知識

C#中的IDisposable形式用法詳解。本站提示廣大學習愛好者:(C#中的IDisposable形式用法詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是C#中的IDisposable形式用法詳解正文


本文實例講述了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#法式設計可以或許有所贊助。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved