2010-07-22 37 views
4

我想知道是否有關於處置一次性物品(處於財產/公共領域而不是私人成員)的一次性物品的處置方面的任何公約。例如,一個DataSet包含DataTable,一個SqlCommand包含一個SqlConnection。處理嵌套一次性物品?

顯而易見的情況是,一個班級會處理它擁有的所有一次性物品,剩下的部分將會丟棄。是否存在這樣的約定?如果是這樣,.NET庫如何確定誰擁有什麼?我怎樣才能找出嵌套對象是否被丟棄?

PS:我一直想知道這一段時間,顯然這樣有別人:What gets disposed when SqlCommand.Dispose is called?

編輯1:發現,處置的DataSet,不出售其表。

// Fill dataset from sqldataadpater. 
foreach (DataTable dt in dataSet.Tables) 
{ 
    dt.Disposed += Program.DisposedEventHandler2; 
} 
Console.WriteLine("Disposing dataset"); 
dataSet.Dispose(); //Event not fired here. 
Console.WriteLine("Disposing datatables maually"); 
foreach (DataTable dt in dataSet.Tables) 
{ 
    dt.Dispose(); //Event fired here 
} 
#endregion 

回答

7

我經常遵循的經驗法則是創建一次性對象的類也會處理它,例如:一個SqlCommand不會處理它的連接,因爲它沒有創建它,StreamReader在這個意義上有一個奇怪的行爲,因爲它總是會處理底層的流,即使它是從外部提供的(我覺得這很煩人,請你在投票時投票HERE微軟要解決這個問題)。

+0

有時候它很煩人,這意味着你可以使用'新的StreamReader(新的FileStream(...))'而不必擔心有兩個'使用'語句......通常可以提高可讀性,國際海事組織。 – 2010-07-22 06:36:24

+0

@Jon:我明白爲什麼BCL團隊選擇這個API設計。它指導.NET開發人員「成功的基石」(就像Rico Mariani所說的那樣)。但是,我錯過了重載的枚舉或布爾標誌,命令'StreamReader'使流保持活着。在當前的設計中,使流保持活動狀態意味着您將不得不使用'class DoNotDisposeStreamDecorator:Stream'封裝流。 – Steven 2010-07-22 06:46:34

+0

是的,我自己就有這樣一個裝飾器... – 2010-07-22 07:21:49

3

我要說的是通常容器將處理任何包含一次性項目 - 底層流的StreamReader處置,例如 - 但通常我會用一個單獨的using聲明反正處置各項目。

「所有權」的任何概念都只是在文檔和約定中。基本上你必須知道什麼會處理什麼,這通常意味着閱讀文檔並希望它清楚。不幸的是,它並不總是這樣做:(

請注意,這裏沒有單一的正確答案 - 有時您可能希望某種類型的行爲是單向的,有時是另一種行爲。有些類型顯式允許您聲明自己是否有效地轉移資源的所有權,雖然大多數不是。

+0

但是,當我使用一個數據集,例如,我使用查詢讀取,我希望處置數據表(和數據表包含datacolumns等...)它包含手動?我真的想不出一個優雅的方式來做到這一點。 – apoorv020 2010-07-22 06:29:34

+0

我最擔心的是BCL庫,因爲他們的處理方法沒有文檔,我使用它們很多。 – apoorv020 2010-07-22 06:31:55

+0

@ apoorv020:'DataTable'和'DataSet'在某種程度上是古怪的。除非您使用遠程處理,否則根據我的意識,您不需要處理它們。他們真的只是一次性的,因爲他們是遠遠不夠的。它們繼承了MarshalByValueComponent的可處置性。 – 2010-07-22 06:32:49

0

最好的方法是向嵌套IDisposable項目提供嵌套項目是否應與容器一起處理的指示器,除非項目的使用壽命永遠不會超過容器的使用壽命(在這種情況下,處理容器可以處理該物品),或者可以確定除容器之外的最後一個實體需要包含的物品將意識到其存在和需要處置(意味着容器不必擔心處置,因爲其他項目可以處理它)。

作爲一個簡單的例子,假設一個人正在設計一個UI框架,並且想要提供一個應該顯示Picture的控件,並提供了一種代碼可以提供一個圖像來顯示的方法。進一步假設某些類型的Picture有資源需要處置。在某些情況下,代碼可能希望在多個控件上顯示某個Picture,這些控件可能並不全部同時處理。在這種情況下,如果處置控制權就是處置它的圖像就會很糟糕。另一方面,還有其他一些情況,代碼可能會爲了顯示目的而創建一張圖片,將其提供給控件,然後再不再關心它。在這種情況下,提供圖片的代碼可能知道圖片應該在控件不再需要時處理,但可能不知道何時會發生。

使用參數指示圖片是否應該爲Disposed將允許在上述兩種情況下使用乾淨的代碼。 Winforms使用的另一種方法是當控件的圖片更改或Image屬性更改時發生事件。將控件的Image屬性設置爲需要處理的圖像的代碼可以使用這些事件來處理它。