国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

C#資源釋放方法實例分析

2020-01-24 01:15:57
字體:
來源:轉載
供稿:網友

本文實例講述了C#資源釋放方法。分享給大家供大家參考,具體如下:

1、try{}finally{}

2、using

只有類型實現了IDisposable接口并且重寫Dispose()方法可以使用using語句實現資源釋放.

首先來看MSDN中關于這個接口的說明:

[ComVisible(true)]public interface IDisposable{ // Methodsvoid Dispose();}

1.[ComVisible(true)]:

指示該托管類型對 COM 是可見的.

2.此接口的主要用途是釋放非托管資源。

當不再使用托管對象時,垃圾回收器會自動釋放分配給該對象的內存。但無法預測進行垃圾回收的時間。另外,垃圾回收器對窗口句柄或打開的文件和流等非托管資源一無所知。將此接口的Dispose方法與垃圾回收器一起使用來顯式釋放非托管資源。當不再需要對象時,對象的使用者可以調用此方法。

一、基本應用

1.我們來定義一個實現了IDisposable接口的類,代碼如下:

public class TestClass :IDisposable{  public void DoSomething()  {    Console.WriteLine("Do some thing....");  }  public void Dispose()  {    Console.WriteLine("及時釋放資源");  }}

2.我們有兩種方式來調用:

2.1.第一種方式,使用Using語句會自動調用Dispose方法,代碼如下:

using (TestClass testClass = new TestClass()){  testClass.DoSomething();}

2.2第二種方式,現實調用該接口的Dispose方法,代碼如下:

TestClass testClass = new TestClass();try {  testClass.DoSomething();}finally{  IDisposable disposable = testClass as IDisposable;  if (disposable != null)  disposable.Dispose();}

兩種方式的執行結果是一樣的。

2.3.使用try/catch/finally的好處是,捕獲異常后可以進行處理與此同時也可以釋放資源;但是使用using,有異常也可以釋放資源,只是無法對異常進行處理,直接將異常放行,而已實際上這兩種方法對資源的釋放上是一樣的.

二、Disposable 模式

1.在.NET種由于當對象變為不可訪問后將自動調用Finalize方法,所以我們手動調用IDisposable接口的Dispose方法和對象終結器調用的方法極其類似,我們最好將他們放到一起來處理。

我們首先想到的是重寫Finalize方法,如下:

protected override void Finalize(){  Console.WritleLine("析構函數執行...");}

當我們編譯這段代碼的時候,我們發現編譯器會報如下的錯誤: 這是因為編譯器徹底屏蔽了父類的Finalize方法,編譯器提示我們如果要重寫Finalize方法我們要提供一個析構函數來代替,下面我們就提供一個析構函數:

~TestClass() { Console.WriteLine("析構函數執行..."); }

實際上這個析構函數編譯器會將其轉變為如下代碼:

protected override void Finalize(){  try {    Console.WritleLine("析構函數執行...");  }  finally {    base.Finalize();  }}

2.然后我們就可以將Dispose方法的調用和對象的終結器放在一起來處理,如下:

public class TestClass: IDisposable{  ~TestClass()  {    Dispose();  }  public void Dispose()  { // 清理資源  }}

3.上面實現方式實際上調用了Dispose方法和Finalize方法,這樣就有可能導致做重復的清理工作,所以就有了下面經典Disposable 模式:

private bool _isDisposed = false;public void Dispose(){  Dispose(true);  GC.SupressFinalize(this);}protected void Dispose(bool Diposing){  if(!_isDisposed)  {    if(Disposing)    {      //清理托管資源    }    //清理非托管資源  }  _isDisposed=true;}~TestClass(){  Dispose(false);}

3.1. SupressFinalize方法以防止垃圾回收器對不需要終止的對象調用 Object.Finalize()。

3.2. 使用IDisposable.Dispose 方法,用戶可以在可將對象作為垃圾回收之前隨時釋放資源。如果調用了 IDisposable.Dispose方法,此方法會釋放對象的資源。這樣,就沒有必要進行終止。IDisposable.Dispose 應調用 GC.SuppressFinalize 以使垃圾回收器不調用對象的終結器。

3.3.我們不希望Dispose(bool Diposing)方法被外部調用,所以他的訪問級別為protected 。如果Diposing為true則釋放托管資源和非托管資源,如果 Diposing等于false則該方法已由運行庫從終結器內部調用,并且只能釋放非托管資源。

3.4.如果在對象被釋放后調用其他方法,則可能會引發 ObjectDisposedException。

三、實例解析

1.下面代碼對Dispose方法做了封裝,說明如何在使用托管和本機資源的類中實現 Dispose(bool) 的常規示例:

public class BaseResource : IDisposable{  // 非托管資源  private IntPtr _handle;  //托管資源  private Component _components;  // Dispose是否被調用  private bool _disposed = false;  public BaseResource() { }  public void Dispose()  {    Dispose(true);    GC.SuppressFinalize(this);  }  protected virtual void Dispose(bool disposing)  {    if (!this._disposed)    {      if (disposing)      {        // 釋放托管資源        _components.Dispose();      }      // 釋放非托管資源,如果disposing為false, 只有非托管資源被釋放      CloseHandle(_handle);      _handle = IntPtr.Zero;      // 注意這里不是線程安全的    }    _disposed = true;  }  // 析構函數只會在我們沒有直接調用Dispose方法的時候調用  // 派生類中不用在次提供析構函數  ~BaseResource() { Dispose(false); }  // 如果你已經調用了Dispose方法后再調用其他方法會拋出ObjectDisposedException  public void DoSomething()  {    if (this._disposed)    {      throw new ObjectDisposedException();    }  }}public class MyResourceWrapper : BaseResource{  // 托管資源  private ManagedResource _addedManaged;  // 非托管資源  private NativeResource _addedNative;  private bool _disposed = false;  public MyResourceWrapper() { }  protected override void Dispose(bool disposing)  {    if (!this._disposed)    {      try      {        if (disposing)        {          _addedManaged.Dispose();        }        CloseHandle(_addedNative);        this._disposed = true;      }      finally      {        base.Dispose(disposing);      }    }  }}

2.使用CLR垃圾收集器,您不必再擔心如何管理對托管堆分配的內存,不過您仍需清理其他類型的資源。托管類通過IDisposable接口使其使用方可以在垃圾收集器終結對象前釋放可能很重要的資源。通過遵循disposable模式并且留意需注意的問題,類可以確保其所有資源得以正確清理,并且在直接通過Dispose調用或通過終結器線程運行清理代碼時不會發生任何問題。

希望本文所述對大家C#程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 海宁市| 山阴县| 习水县| 葫芦岛市| 前郭尔| 湘西| 紫金县| 教育| 木兰县| 凤山县| 涪陵区| 绥阳县| 肥东县| 惠安县| 西乌| 湘潭县| 浠水县| 巨野县| 萍乡市| 庄浪县| 呼伦贝尔市| 岢岚县| 于都县| 丘北县| 福海县| 杭锦后旗| 获嘉县| 临清市| 洛阳市| 神池县| 娱乐| 和政县| 儋州市| 杭锦旗| 泰兴市| 普兰县| 噶尔县| 四川省| 托克托县| 邵东县| 常山县|