試圖瞭解IDisposable我有幾個問題,大多數答案沒有明確說明。有關C#Dispose如何工作的更多信息
如果我們調用處理的對象上,是否配置在當時還是剛下課的成員,我們想清理對象,整個對象後來由GC被破壞。
當我們在dispose方法中禁止終結器後,GC仍然會清除我們在處理中沒有清理的所有類成員?
試圖瞭解IDisposable我有幾個問題,大多數答案沒有明確說明。有關C#Dispose如何工作的更多信息
如果我們調用處理的對象上,是否配置在當時還是剛下課的成員,我們想清理對象,整個對象後來由GC被破壞。
當我們在dispose方法中禁止終結器後,GC仍然會清除我們在處理中沒有清理的所有類成員?
一旦對象的所有引用都以非確定的方式消失,對象將被垃圾收集。 Garbage collection 從MSDN:
垃圾收集。
GC.Collect方法被調用。幾乎在所有情況下,您都沒有 來調用此方法,因爲垃圾收集器連續運行。 此方法主要用於獨特的情況和測試。
1)當你調用處理的對象上,發生的是,在其Dispose()方法的代碼運行。這段代碼當然可以調用一個或多個字段的Dispose(),但這不是必需的。
它也可能調用基類'Dispose(true)
(如果有的話)(通過base.Dispose()
),但這是使用Dispose的成語; Dispose(bool)
不是IDisposable
接口的一部分。
2)僅對調用SuppressFinalize()的特定對象抑制終結器。它不會影響任何其他對象(包括由調用SuppressFinalize()的對象的字段所保存的任何對象)。
首先,這裏有很多重複的問題在這個主題。如果真的沒有其他答案明確地回答你的問題,在這裏他們是,但我希望這是重複的關閉。
首先,Dispose
只是一種方法,一種普通的方法。它根本不處理垃圾收集。
那麼Dispose會做什麼?它應該用來清理非託管資源,例如文件句柄,窗口句柄等等。NET垃圾收集器不知道。
因此,要回答問題1:「是」,當您在對象上調用Dispose
時,它將在此處處理。班級上沒有設置標記以指示稍後進行清理。
由於Dispose不處理垃圾收集,您可以在處理垃圾收集後輕鬆保留對象的引用,並且不會垃圾收集。只有在沒有更多的對象引用時纔會發生垃圾收集。即使您沒有在對象上調用Dispose
,也會發生這種情況,但不會發生,因爲您會在對象上調用Dispose
。第二個問題:當GC在完成了終結器循環後收集對象時,GC將清理對象+它引用的任何對象,不再有任何引用(與對象相鄰)。這發生在某個點,並不一定全部一次。
抑制終結者只是確保GC不會做超過必要的工作,通過說「當你找到這個對象,並確定它有資格收集,然後繼續收集它,我已經照顧的'定稿'清理,所以你不必「。
首先,最重要的是你需要明白,處理一個物體和垃圾收集對象是completely different things - 確保你不要混淆兩者!
如果我們調用處理的對象發生了唯一的事情是,Dispose
方法被調用的。這可能是Dispose
方法然後繼續呼叫GC.SuppressFinalize
,但然後再次它可能不會做任何事情在所有 - 完全取決於實施。
當我們調用GC.SuppressFinalize
的只件事發生的是,它請求GC不會調用對象的終結當對象被收集(幾乎彷彿對象並沒有終結在第一地點)。
因爲它發生在一個常見的模式是其中有一個終結,也能實現IDisposable
使非託管資源可以deterministicly清理對象 - 如果這種情況發生則沒有必要爲GC調用終結作爲當我們調用Dispose
時,已經完成了在終結器中完成的工作 - 調用GC.SuppressFinalize
對GC來說只是一個友好提示,畢竟它並不需要調用終結器。
您需要閱讀Ravi發佈的內容並瞭解垃圾收集在C#中的工作方式。 Dispose只是一個方便的地方來關閉文件,網絡連接,SQL服務器連接等。它不釋放內存。 – Corey 2013-03-01 12:41:14
IDisposeable在任何方面都不神奇。它確實與GC或任何類似的東西有關係。它只是一種模式,如果它不存在於.NET中,您可以自己編寫該接口以達到相同的效果。 – 2013-03-01 12:42:26
處理對象和垃圾回收是[**完全**不同的主題](http://stackoverflow.com/questions/339063/what-is-the-difference-between-using-idisposable-vs-a-destructor-in -c) - 確保你不會混淆兩者! – Justin 2013-03-01 12:47:38