托管資源與非托管資源
在.net中,對象使用的資源分為兩種:托管資源與非托管資源。托管資源由CLR進行管理,不需要開發人員去人工進行控制,.NET中托管資源主要指“對象在堆中的內存”;非托管資源指對象使用到的一些托管內存之外的內資源(例如操作系統的資源),CLR不會管理這些資源,需要開發人員去控制。.NET對象使用到的非托管資源主要有I/O流、數據庫連接、Socket連接、窗口句柄等直接與操作系統操作的相關資源。
管理非托管資源
當一個對象不再使用時,我們應該將它使用的非托管資源釋放掉,歸還給操作系統,不然等到CLR將它在隊中的內存回收之后。這部分內存就會變成不可達狀態。只能等到整個應用程序運行結束后才能歸還給系統。所以我們應當在該對象實例處于“可達”狀態時,既有對象引用指向它時釋放非托管資源。
利用IDisposable接口構造含有非托管資源類型的對象
在.net類庫中有一個IDisposed的接口。幾乎每一個使用非托管資源的類型都應該實現這個接口。那么如果我們看到實現此接口的類型,也應該第一時間想到該類型中包含非托管資源。IDispose接口是管理對象非托管資源的一種原則。代碼如下:
interface IDisposable
{void Dispose();
}
class ABase:IDisposable
{bool _disposed = false;public bool Disposed{get{return _disposed;}}public ABase(){}public void Dispose(){if(_disposed){Dispose(true);GC.SuppressFinalize(this);_disposed = true;}}protected virtual void Dispose(bool disposing){if(disposing){//release member's unmanaged resource}// release ABase's unmanaged resource}~ABase{Dispose(false);}
}
class A : ABase
{public A(){}protected override void Dispose(bool disposing){if(disposing){// release member's unmanaged resource}// release A's unmanaged resource// release base class's unmanaged resourcebase.Dispose(disposing);}}
class B:A
{public B(){}public void Dosomething(){if(Disposed)// if released, throw exception{throw new ObjectDisposedException(...);}// do something here}protected override void Dispose(bool disposing){if(disposing){// release member's unmanaged resource}// release B's Unmanaged resourcebase.Dispose(disposing);}
}