2009-10-07 70 views
1

我有一個DataGridView正在定期通過數據綁定對象填充和行數有可能變大,一個「記錄週期」中說成千上萬。的DataGridViewRow不被垃圾收集

當一個新的「記錄週期」開始,因爲底層數據源被清除網格被清除,過程又重新開始。

這是所有罰款,但因爲之前的運行需要一定的時間,所有這些以前的行成爲2代對象,只收集一個完整的GC垃圾。

但是,它需要兩個完整GC的清除它們,因爲第一個他們都發送到終結隊列中。這意味着他們周圍的時間長達兩倍的時間。我發現DataGridViewRow沒有一個終結器方法,但它確實繼承了DataGridViewBand對象,它通過它的公共Dispose()方法調用GC.SuppressFinalize(this)。

所以我的問題是 - 爲什麼我的DataGridViewRows沒有得到收集了第一個完整的GC,並使其到終結隊列中等待下一次呢?我在這裏假設沒有終結器的任何對象不應該被放置到終結器隊列中,任何有一個但調用GC.SuppressFinalize的對象也不會放在隊列中。假設?)

謝謝。

回答

3

GC.SuppressFinalize(this)的調用基本上告訴GC,最終化期間發生的清理行爲已經發生(通過調用Dispose()),並且它不需要再次執行終結。這與對象是否放在最終隊列上無關。

在任何時間一個終結對象被實例化(new編),它被放置在終止隊列。完成隊列僅在每個完整GC採集(Gen2採集)期間處理。可終結對象的問題之一是它們在實際收集之前將經歷至少一個額外的GC循環。

+0

謝謝Scott,所以看起來我的理解有點瑕疵?事實上,一個行使用Finalize方法從一個對象繼承意味着它將始終放在隊列中,並受到雙重GC的清除,我所看到的是正確的?哎喲! – Andy 2009-10-07 19:37:55

+1

@安迪:是的,你的理解是不正確的。由於'DataGridViewRow'繼承自可終結對象,因此它實際上也成爲可終結對象,並被放置在隊列中。你所看到的是正確的。 Clear()'方法很可能不會處理行,在這種情況下,您可以在調用Clear()之前(或之後)手動處理它們,儘管我不確定這是否可行。 (這取決於實現的方式。)或者,您可能可以在底層數據源上調用Dispose(),這可能也會起作用。 – 2009-10-07 19:42:46

+0

嗯,有趣。我曾嘗試調用Clear(),但由於'無法清除數據綁定網格',我得到錯誤,本質上是因爲數據綁定負責填充/清除這似乎足夠公平。雖然沒有想過在數據源上調用dispose,但會放棄它。 – Andy 2009-10-07 19:48:47

0

如果你不處理你的對象,那麼它們將不會被終止。

+0

我同意,但我不直接創建行,它們是通過數據綁定創建的。我還需要以某種方式調用它們嗎? – Andy 2009-10-07 19:22:50