用IDisposable接口釋放.NET資源

發表于:2007-05-25來源:作者:點擊數: 標簽:IDisposable.NET釋放接口資源
使用Dispose 模式能夠適當地釋放資源,但會增加系統開銷。 by Mickey Williams 通過使用Dispose模式可以適當地釋放非內存資源,比如 數據庫 連接、Win32 interop組件和操作系統的句柄。你不要指望垃圾收集器能夠立即將資源釋放掉,因為垃圾收集器是由于管制
使用Dispose 模式能夠適當地釋放資源,但會增加系統開銷。
by Mickey Williams

通過使用Dispose模式可以適當地釋放非內存資源,比如數據庫連接、Win32 interop組件和操作系統的句柄。你不要指望垃圾收集器能夠立即將資源釋放掉,因為垃圾收集器是由于管制堆(Managed Heap)的內存緊張時才觸發的。你可以快速消耗掉例如數據庫連接等少量資源,但會給程序的擴展性造成副面影響。在不必要的時候不能實現Dispose模式,因為它可能會增加系統開銷,而這在很多情況下是可以避免的。

.NET當中Dispose 模式是由一個IDisposable接口來實現的,它包括一個簡單的方法--Dispose:

clearcase/" target="_blank" >cc>
interface IDisposable
{
	void Dispose();
} 

最明顯的例子是在一個類里當類的實例搶占住一個非管制資源(unmanaged resource)時必須實現IDisposable,比如一個本地數據連接或是操作系統的句柄。

另外,記下一個經常被忽略的應該實現IDisposable接口的例子。當一個類實現IDisposable時,實例的正確用法是當對象不在需要時調用Dispose方法刪除它,因此,在你實現一個類,而該類又包含其他實現IDisposable的類時,必須調用Dispose方法。這通常意味著在該類中你必須實現IDisposable,即使它無法直接處理非管制資源。

以下是一個實現IDisposable接口的典型模式:

public class SlalomRacer: IDisposable
{
    bool _disposed = false;

    public bool IsDisposed
    {
        get { return _disposed; }
        set { _disposed = value; }
    }

    ~SlalomRacer()
    {
        InternalDispose(false);
    }

    public void Dispose()
    {
        InternalDispose(true);
    }

    protected void InternalDispose(bool disposing)
    {
        if(disposing)
        {
            GC.SuppressFinalize(this);
            _managedThing.Dispose();
        }
        _unmanagedThing.Dispose();
    }
    [...]
}


在前面的代碼片斷中,當IDisposable被實現時,可以通過兩種方法調用disposal代碼。首先,如果你直接調用Dispose方法,所有管制和非管制對象均會被列為被清除目標??梢钥吹浇K止操作會執行一個阻止對象被清除掉的優化的步驟。還注意到可以安全地多次調用Dispose方法。調用dispose方法之后,會使用一個標志來確保這個對象上的任何一個方法都不能被調用,示例代碼如下:

public void SeekHotTub()
{
    if(IsDisposed)
        throw new ObjectDisposedException("BT");
}

ObjectDisposedException會提醒你前面已經使用了一個disposed對象。在一個使用過disposed對象上調用其他方法時引發異常是完全有必要的--畢竟,你不能再次使用這些disposed對象。

其次,如果你不調用這個Dispose方法,終止操作會自己調用Dispose(false),它會采用一個和前段代碼稍有不同的代碼路徑。第一,不清除那些管制對象,即使他們也實現了IDisposable接口。你無法確定對象引用是有效的--這些對象可能在等待操作的終止,或者已經被終止了。第二,也沒有必要去調用GC.SuppressFinalization,因為這些對象已被終止使用了。

最后,如果你在使用C#,你應該利用其語言固有的對IDisposable接口的支持來實現對象清除,你可以使用以下聲明:

using(SlalomRacer mickey = new SlalomRacer())
{
    // use mickey here
    mickey.RunGates();
    mickey.GetStitches();
}
// mickey disposed automatically here

C#編輯器會適當地發出調用Dispose方法的IL代碼,即使會引發異常。

原文轉自:http://www.anti-gravitydesign.com

評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97