VB.NET中Finalize與Dispose的區別

Creative Commons License
本作品採用知識共享署名-非商業性使用-相同方式共享 2.5 中國大陸許可協議 進行許可。

 

在VB.NET框架中,類沒有真正意義的析構函數,但是有兩種方式可以實現析構函數的功能:一個是Finalize方法,用於被動的釋放資源;另一個是Dispose方法,可以主動的釋放資源。


Finalize方法由垃圾回收系統(GC)自動調用。使用Finalize方法需要注意以下要點:

1. 延遲調用特性
由於垃圾回收是由.NET框架通過一個獨立的線程自動調用的,因此當所有指向對象的變量都設置爲Nothing之後,Finalize方法不會立即被調用。

2. 訪問限制
一方面,託管對象的資源釋放是由垃圾回收系統完成的,在Finalize方法中不必管理其它託管對象的釋放工作;另一方面,也不要在Finalize方法中訪問任何託管對象,因爲這些託管對象很可能已經被銷燬。在Finalize方法中應該總是釋放那些非託管對象(如文件句柄等)的資源。

3. 調用限制
永遠不要在程序中主動調用Finalize方法,調用Finalize方法的唯一方式是將引用對象的變量設置爲Nothing。


由於Finalize方法的種種限制,特別是延遲調用特性,我們不得不使用一種更主動的方式來釋放資源,那就是實現IDisposable.Dispose方法。使用Dispose方法需要注意以下要點:

1. 立即執行
與Finalize的延遲調用特性不同,Dispose方法被設計成使用者主動調用並立即執行。這是一種可控制的釋放資源的方法。

2. 託管資源的釋放
除了非託管對象的釋放工作之外,Dispose還要負責託管對象的釋放(註釋1) ,這一點Finalize方法是做不到的。

3. 調用不受限制
程序中可以多次調用對象的Dispose方法。通常情況下,只有第一次調用時釋放資源。


如何選擇釋放資源的方法呢?是實現Finalize還是實現Dispose?

如果不介意延遲調用並且對象內部僅有非託管資源需要釋放,實現Finalize方法是很好的選擇。選擇Finalize方法完全取決於我們對延遲調用的容忍程度,試問當我們想要關閉一個文件時系統卻沒有及時響應,這樣的情況是否允許?

如果對象內部存在其它託管對象並且這些託管對象實現了Dispose方法,那麼實現Dispose方法用於釋放內部的託管對象將是唯一的選擇。因爲只有在Dispose方法中纔可以調用其內部對象的Dispose方法。

如果要實現的類是一個基類,並且不想讓繼承類的釋放過程過於複雜,請使用Dispose-Finalize模式實現釋放資源的功能。

註釋1:釋放託管對象的資源


有兩個方法可以釋放託管對象的資源:如果託管對象實現了IDisposable.Dispose方法,調用這個方法;然後將指向託管對象的變量設置爲Nothing。可以用下面的方法一站式處理:

 

 

© 醜小鴨技術專欄 | 查看原文

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章