標籤:自訂格式 調用 隨機 base 影響 elf ddd border 對象
本文執行個體講述了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#程式設計能夠有所協助。
除聲明外,
跑步客文章均為原創,轉載請以連結形式標明本文地址
C#中的IDisposable模式用法詳解
本文地址: http://www.paobuke.com/develop/c-develop/pbk23539.html
相關內容C#自訂音樂播放器進度條C#使用winform簡單匯出Excel的方法基於C#實現簡單的隨機抽獎小程式詳解C#編程中.NET的弱事件模式
C# WebClient類用法執行個體C#中使用IFormattable實現自訂格式化字串輸出樣本C#編程實現向並口裝置發送指令、擷取並口裝置的狀態C#的回調機制淺析
C#中的IDisposable模式用法詳解