2010-02-11 83 views
6

爲了有條件地在所有主要公開方法的開頭部署ObjectDisposedException,是否有任何要跟蹤其他線程安全類型的經典bool disposed字段?IDisposable,ObjectDisposedException和線程安全類型

我見過這種模式在網上幾個地方推薦,但我不知道作者是否正確使用它,所以這個問題假設他們是。

在這種情況下,似乎確保條件評估超出條件評估的唯一方法是在每個暴露成員的整個主體上使用同步機制,例如lock(),包括Dispose(布爾)方法。這不會使這個類型再次有效地單線程嗎?

如果這是真的,那麼使用它就沒有意義了,因此在一些IDisposable實現中你不能依賴ObjectDisposedException機制 - 那麼爲什麼我們會使用這種機制,如果它不是'必要嗎?

====

我想了IDisposable和的ObjectDisposedException只是不一起去的線程安全的類型。

+0

另請參閱:http://stackoverflow.com/questions/170028/how-would-you-simplfy-entering-and-exiting-a-readerwriterlock – 2010-02-11 21:02:57

回答

4

也許一個更有效的方法使用ReaderWriterLockSlim時,使一個線程安全的對象不會被丟棄。讓所有公共方法在執行時獲得讀鎖,並在完成後釋放它。有Dispose獲得作家鎖定。它會等到所有其他方法完成後纔會獲得寫入鎖定。然後在它獨佔的寫入鎖內設置isDisposed。在Dispose完成後,任何對公共方法的調用都可以看到isDisposed並拋出ObjectDisposedException

ReaderWriterLockSlim

http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx

+0

很酷的想法。有樣品?沒有在ReaderWriterSlimLock上找到文檔。這是你以前見過的東西,還是你剛纔頭腦風暴的東西? – 2010-02-11 19:03:53

+0

只是頭腦風暴,但我認爲它應該適合您的要求。我在原來的答案中拼錯了它,它是'ReaderWriterLockSlim'。我添加了一個MSDN文檔的鏈接。 – 2010-02-11 19:10:16

+0

實際上,這幾乎可以工作,除了FXcop正確地指出ReaderWriterLockSlim實現了IDisposable並且應該與對象資源的其餘部分一起處理。所以一旦調用了dispose,我將不再能夠獲得讀鎖,以便測試該對象是否已被處置。 – 2010-02-12 23:49:21

3

如果你的對象的行爲會有所不同,如果它已經被設置,如果它很可能是它被安置後,將被使用,那麼你需要保持跟蹤這個。拋出ObjectDisposedException比拋出任何隨機異常更好,如果對象已經處理並且不首先檢查將發生。

+0

是的,但這個問題是關於如何在多線程場景中確定地拋出ObjectDisposedException。 – 2010-02-15 19:25:45

+0

@Jason:在這種情況下,編輯你的問題說出來。 – 2010-02-15 22:35:39

0

鑑於「Disposed」布爾值只在一個地方更新,並且調用者在調用Disposed後使用該對象時會出錯。

我認爲在Dispose被調用後「大部分時間」拋出ObjectDisposedException已經足夠了。我將ObjectDisposedException看作是調試幫助程序,而不是調用程序應該捕獲的東西。

0

如果在處理對象時有可能調用某個方法,則應該以這樣的方式定義該方法的語義,即在處置對象上調用該方法不會造成任何問題。在可能或不可能有問題的情況下,應該使用「嘗試/做」模式。如果微軟在Control.BeginInvoke中遵循了這個原則,就會有一個「Control.BeginInvoke」和一個「Control.TryBeginInvoke」;後者將被明確定義爲返回false,如果控件在行爲排隊之前處理,則不做任何事情(請注意,Control.BeginInvoke返回true不能保證控件在實際運行之前不會被處理)。這種模式在顯示更新場景中非常有用:如果控件不處理,我希望它的更新例程運行;如果它在更新例程運行之前被丟棄,那麼更新將變得沒有意義,並且其失敗並不會成爲問題。