託管資源與非託管資源
在.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 resource
base.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 resource
base.Dispose(disposing);
}
}