2010-06-30 66 views
10

我在VS做一些ASP.NET開發,剛剛發現了一個有趣的小代碼建議(我認爲他們來自coderush,但我可能是錯的)。爲什麼我需要調用ASP.NET控件上的dispose?

每當我創建控件時,它告訴我應該爲他們使用「使用」語句。儘管我對這裏發生了什麼感到困惑。與使用我的代碼看起來是這樣的:

using (HtmlTableRow tableRow = new HtmlTableRow()) 
{ 
    tableRow.Attributes.Add("class", isOddRow ? "OddRow" : "EvenRow"); 
    listingTable.Rows.Add(tableRow); 
    addCell(tableRow, row, "issueId"); 
    addCell(tableRow, row, "Title"); 
    addCell(tableRow, row, "Type"); 
    addCell(tableRow, row, "Summary"); 
} 

所以我期待,在using語句的結束,它會調用在tablerow的處理。但是,MSDN庫中的文檔說:

Dispose方法使控制 處於不可用狀態。在調用 這種方法後,您必須釋放對控件的所有 引用,以便它佔用的內存可以是 垃圾回收回收。

所以我希望我現在有一個不可用的對象在我的控制結構中,所以它會打破或不呈現或什麼。然而,一切似乎都很好。

所以我想知道爲什麼所有的控件都是一次性的?這是否僅僅是因爲它們中的一部分會使它們成爲一次性意味着一個調用在頂層處理的調用可以遞歸地傳遞給所有子控件?

我想我會理解,如果不是因爲文檔明確指出處置控件使其無法使用......文檔是否錯誤?

+0

如果我們不使用「使用」塊,我們如何處理孤立的對象(@Toby提到)? – Lijo 2012-11-21 17:38:27

回答

14

你不應該這樣做。你需要做的是確保listingTable在Controls集合中,以便它在頁面被丟棄時被丟棄。然後,listingTable對象負責正確處理其所有子項。

這就是爲什麼所有的Control對象實現IDisposable接口。這樣,每個父母控制器都可以在其所有孩子上調用Dispose,而無需先測試/投射每個孩子。每個控件都獨自負責確定在調用Dispose方法時是否確實有任何需要清理的內容。

該文檔沒有錯。如果在處置過程期間實現IDisposable 並且具有實際被清理的狀態數據的任何正確編寫的對象應該拋出ObjectDisposedException,如果它的任何公共/受保護/內部屬性或方法在處置後被訪問。 (在調用Dispose之後假設無效狀態)。如果某些類型實際上沒有任何清理內容,則不會理會這個規則,也不必擔心無效狀態。

原因你得到一個建議,把它包在using塊,因爲分析器沒有意識到listingTable將出售其Rows收集,這將配置每個已添加到它的行對象。此外,如果在HtmlTableRow tableRow = new HtmlTableRow()listingTable.Rows.Add(tableRow)之間拋出異常,則HtmlTableRow對象將是「孤立」的,並且不在任何其他對象的IDisposable層次結構中。代碼分析希望你使用try/finally塊來立即處置HtmlTableRow,如果發生這種情況。

+1

謝謝。我對這個問題大部分都有懷疑,但是對於在這裏發生的事情有更詳細的瞭解。我甚至不考慮控制的「孤立」。 – Chris 2010-06-30 16:09:32

+0

如果我們不使用「使用」塊,我們如何處理'孤立的對象? – Lijo 2012-11-21 17:04:24

+0

@Lijo:使用try/finally塊 – Toby 2013-01-31 16:32:40

相關問題