產生了兩個問題(**中紅色標註區域):
問題1:為什麼在析構函式中呼叫的是「dispose(false);」,也就是為什麼gc垃圾**機制在**對
象的時候只**或者釋放非託管資源,而不**託管資源?
問題2:在「dispose()」中「gc.suppressfinalize(this);」是什麼意思?
上網搜了寫資料,終於了解了這種設計的用意和優點:
參考資料:
解答問題1:
在.net的物件中實際上有兩個用於釋放資源的函式:dispose和finalize。finalize的目的是用於釋放非託管的資源,而dispose是用於釋放所有資源,包括託管的和非託管的。
在這個模式中,通過乙個變數「disposing」來區分是客戶呼叫(true)還是gc呼叫(false)。
這是因為,dispose()函式是被其它**顯式呼叫並要求釋放資源的,而finalize是被gc呼叫的。
在gc呼叫的時候myresource所引用的其它託管物件(component)可能還不需要被銷毀,並且即使
要銷毀,也會由gc來呼叫。因此在finalize中只需要釋放非託管資源即可。
解答問題2:
由於在dispose()中已經釋放了託管和非託管的資源,因此在物件被gc**時再次呼叫finalize是
沒有必要的,所以在dispose()中呼叫gc.suppressfinalize(this)避免重複呼叫finalize。
因此,上面的模式保證了:
1、 finalize只釋放非託管資源;
2、 dispose釋放託管和非託管資源;
3、 重複呼叫finalize和dispose是沒有問題的;
4、 finalize和dispose共享相同的資源釋放策略,因此他們之間也是沒有衝突的。
在c#中,這個模式需要顯式地實現,其中c#的~myresource()函式代表了finalize()。
優點:
1、如果客戶沒有呼叫dispose(),未能及時釋放託管和非託管資源,那麼在垃圾**時,還有機會執
行finalize(),釋放非託管資源,但是造成了非託管資源的未及時釋放的空閒浪費。
2、如果客戶呼叫了dispose(),就能及時釋放了託管和非託管資源,那麼該物件被垃圾**時,不回
執行finalize(),提高了非託管資源的使用效率並提公升了系統效能。
此外還有close()方法,此方法一般和open()方法配合來使用,對於資料庫連線,一般可以逆向操作,比如開啟->關閉,關閉->開啟,而對於檔案操作,一般是關閉檔案,相當於dispose(),而且有的使用者更願意使用close()來釋放資源,所以出現了一下這種相當於介面卡模式的**:
public
void
close()
最後還要再說一點,據msdn上說c#不允許類實現finalize()方法,所以用析構函式來代替。
C 實現IDispose介面
net的gc機制有兩個問題 首先gc並不能釋放所有資源,它更不能釋放非託管資源。其次,gc也不是實時的,所有gc存在不確定性。為了解決這個問題donet提供了析構函式 public class testclass system.idisposable protected的dispose方法,保證不會...
C 實現IDispose介面
net的gc機制有兩個問題 首先gc並不能釋放所有資源,它更不能釋放非託管資源。其次,gc也不是實時的,所有gc存在不確定性。為了解決這個問題donet提供了析構函式 public class testclass system.idisposable protected的dispose方法,保證不會...
如何實現真正的IDispose?
最近在專案開發的過程中,我們的乙個資料同步程式碰到了資源無法釋放的問題。我使用的定位方法是效能計數器 perfmon.msc 顯然這只是乙個很粗礦的判斷。後通過code review我們的 中定義了乙個同步的中間類,該類中會快取大量的中間資料集。而程式中麼有及時的 這些臨時物件,最終我建議該類實現一...