2013-05-20 189 views
2

我正在閱讀一些關於Dispose()方法的文章,發現非託管資源應該從Dispose()方法(或finalize()方法)明確釋放,文章中提到文件句柄和數據庫連接對象是非託管資源。任何人都可以解釋爲什麼這些是不受管理的,如果在Dispose()中處理不當,會發生什麼?我不知道文件句柄是什麼。它們在哪裏存在?非託管資源和Dispose()

回答

5

在這種情況下它可能是最容易想到的是這樣的:

  • 非託管資源是你以Windows API調用返回一個Windows Handle必須在某個時刻被釋放獲得的任何資源。

  • 唯一的另一種資源是內存。如果它是由.Net分配的,則會自動進行管理。 (請注意,有辦法來分配使用Windows API內存;這算作一個非託管資源)

例如,FileStream類調​​用Windows API來打開一個文件,其中FileStream保持內部文件句柄。該文件句柄代表一個非託管資源,必須在某個時候釋放它。

FileStream在幕後使用Windows API函數CreateFile()。它是從CreateFile返回的代表非託管資源的句柄。

如果不釋放這些句柄,他們將繼續分配給程序的持續時間,但有一個非託管資源的所有.NET類提供Finalizer(見下文),以確保它們會通常可以在某個時間點釋放

(但如果你正在寫自己的文件處理類,忘了釋放文件句柄的任何地方所有,直到你的程序退出文件將照常開放。)

通常這種非託管資源將在被釋放兩個的地方:

  • Dispose()方法。這應該是您處理非託管資源的正常方式。

  • The Finalizer。這是最後一招的機制。如果一個類有一個終結器,它將在垃圾收集器清理一個死對象時被調用。如果程序員忘記調用Dispose(),任何具有非託管資源的類都應該有一個終結器來清理。

這是一個簡化,但它會幫助你理解它,我希望。請參閱this MSDN article on the Dispose Pattern

2

有些人認爲非託管資源與Windows API調用或其他類似的東西有關,但這是一個實現細節。非託管資源的基本特徵是其代表了外部實體的狀態的一個方面,該狀態爲了擁有資源的對象的利益而維護,潛在損害其他實體,以及外部實體將繼續維護 - 無用 - 如果所有對業主的引用都被放棄了。請注意,外部實體可以是任何地方的任何地方。 Windows API句柄代表了可能性的一小部分(獲取句柄的對象要求Windows使系統的某些方面可用於其獨佔使用,而不利於任何其他希望使用它們的代碼)。外部實體完全可能在同一個程序集內(尤其是資源是鎖定或事件訂閱),或者它可能位於另一個大陸(如果資源是遠程計算機上的文件)。

對象通過通知實體代表它的行爲來釋放資源,這些實體不再需要這樣做。託管資源是一個.NET堆對象,它可能擁有託管或非託管資源的某種組合,但如果資源被放棄,其資源可能會被釋放。