2009-12-02 18 views
12

我有一種方法,其內部有一個try/catch/finall塊。內的try塊中,我聲明SqlDataReader的如下:調用Dispose()當一個對象超出範圍/方法VS完成

   SqlDataReader aReader = null;   
       aReader = aCommand.ExecuteReader(); 

在最後塊,其被設置手動的對象是那些被設置在類級別。因此,實現IDisposable的方法中的對象(如上面的SqlDataReader)是否會自動處理?在執行while循環以獲取閱讀器的內容之後(在調用Close()時應該是Dispose()),在aReader上調用Close()。如果沒有調用Close(),當方法結束或對象超出範圍時,該對象是否會自動關閉/處理?

編輯:我知道的使用()語句,但也有其困惑我的情景。由於

感謝

回答

24

不,對象不會自動外出時的範圍設置。

即使許多IDisposable對象實現了「後備」終結器,以確保它們最終被丟棄,但它們甚至不能保證在被垃圾收集時處理。

您可以承擔任何IDisposable物品的處置責任,最好是將其包裝在using區塊中。

8

您應該使用using {...}塊來包裝你IDisposable的對象 - 在Dispose()方法(這對於SqlDataReader的假冒的Close()方法)將使用塊結束時被調用。如果你不使用using,對象將不會自動配置時,它超出範圍 - 這將是對象最多終結,如果有的話,擺脫資源被垃圾回收時

using (SqlDataReader aReader = aCommand.ExecuteReader()) 
{ 
    // ... do stuff 
} // aReader.Dispose() called here 
-1

可能會在Using聲明幫助嗎?

1

的Dispose模式不做出關於哪些對象調用Dispose上其他對象的任何擔保;它有時會發生,但你不應該在意。相反,確保爲所有IDisposable對象調用Dispose()是您的責任。要做到這一點的最佳方式是使用using聲明。例如:

using (SqlDataReader aReader = aCommand.ExecuteReader()) 
{ 
    // your code 
} 
0

我由語句不解「在最後塊,其被設置手動的對象是那些被設置在類級」。通過在課堂上設定的對象,你的意思是田野嗎?你可能不應該用一種普通的方法來處理這些問題,因爲那樣的話,這些領域的生命週期是不可預知的,並且取決於你碰巧調用了哪些方法。在Dispose方法中實現IDisposable並處理字段會更好。

1

我同意以上全部。你應該確保你叫Dispose()自己,併爲這是與using語句最簡單的方法(你也可以自己做的finally塊 - 這是更詳細的,但有時是必要的)。如果你不這樣做,你可以發現你的應用程序泄漏非託管資源,如句柄,甚至非託管內存,尤其是在某些地方使用了某些COM組件,或者正在調用Win32 API。這顯然會導致性能和穩定性問題,以及資源過度使用。

僅僅是因爲執行IDisposable的對象「應該」實現一個調用他們的Dispose(bool disposing)方法來釋放非託管資源的終結器,並不能保證這會發生,所以您絕對不應該依賴它。有關此點的更多信息,請參閱http://msdn.microsoft.com/en-us/library/b1yfkh5e%28VS.71%29.aspx

另外,要記住的是,如果你的類型有一次性成員,你的類型應該實現IDisposable(除非這些成員的生命週期是由另一種類型管理的,顯然可能會變得凌亂),或者,如果您只在一種方法中使用這些成員,或者實現某個特定的功能,則應考慮在使用它們的方法中將它們設置爲局部變量/參數。

相關問題