我已經閱讀了很多關於C#中的finalizer和IDisposable
。當我終於從這個終結者和IDisposable
這個可怕的混亂中清醒過來時,突然之間,突然之間,出現了這個SafeHandle的事情。我的信念再次完全動搖。我該用什麼?C#使用IDisposable或SafeHandle?
回答
SafeHandle僅在處理Win32 Interop調用時有用。在Win32中,大部分事物都由「句柄」表示。這包括Windows,Mutexes等。因此,.NET SafeHandle使用一次性模式來確保Win32句柄被正確關閉。
因此,如果您使用Win32 Interop調用並獲取Win32句柄,請使用SafeHandle。對於你自己的物體,你會堅持使用IDisposable和終結器。
但[IDisposable](https://msdn.microsoft.com/en-us/library/system.idisposable(v = vs.110).aspx)的整點是釋放*非託管*資源,不是它? 「你自己的對象」聽起來很模糊,因爲對象可以代表一個託管的*和*非託管對象,因爲你是開發者,既可以開發管理代碼,也可以從你的託管代碼中調用你的非託管代碼,你自己定義的「也是模糊的。 –
@zespri - 如果您決定實施IDisposable,那意味着您正在維護類/對象(即它是您的)。如果它是來自第三方庫的對象,則無法實現IDisposable(即,它不是您的)。我不是指應該處理什麼,也不是在非託管代碼中實現IDisposable。 – CodeNaked
但是,如果它是來自第三方(託管)庫的對象,那麼您無法實現'SafeHandle'?僅僅因爲你最初可能沒有直接掌握手柄的能見度呢?對不起,不是好鬥,只是想明白你的意思。 –
對於任何可以表示爲IntPtr的非託管資源,即Win32句柄,由非託管代碼分配的內存等,您都可以/應該使用SafeHandle。如果SafeHandle不合適,但仍需要處理非託管資源,請考慮製作自己的SafeHandle-like類,繼承CriticalFinalizerObject。
在所有其他情況下(即處理管理資源)實現IDisposable。在大多數情況下,你不需要終結器,當調用終結器時,大多數託管資源將不可用,所以在那裏沒有任何事情可做。
在大多數情況下,我的建議是假裝沒有終結器這樣的事情,但是100%確定任何創建的IDisposable對象都會被銷燬。即使終結器是以最佳方式寫入100%,那麼正確處理其一半對象並讓終結器處理另一半的代碼將不如代碼正確處理所有對象並且不使用終結器。儘管通常不會運行的終結器對性能的影響確實不是太糟糕,但終結器難以正確編寫,如果他們的代碼或代碼消耗的不完美,它們會導致Heisenbugs。此外,成功實現終結器通常需要創建一個或多個WeakHandles,其唯一目的是支持終結。
也許最終確定的安全網是值得的成本,但成本可以相當大,安全網不如人們可能想要的那樣可靠。
- 1. 何時不能在Finalizer/IDisposable上使用SafeHandle?
- 2. 當試圖正確使用依賴注入和IDisposable接口時,我應該注入一個SafeHandle實例嗎? C#
- 3. 不使用IntPtr的SafeHandle
- 4. 使用IDisposable
- 5. C#IDisposable使用方法:最佳實踐
- 6. 使用IDisposable C#的MySQL連接#
- 7. 如何將IntPtr轉換爲Cursor或SafeHandle?
- 8. 使用SmtpClient和IDisposable
- 9. SafeHandle和HandleRef
- 10. C#類,subclases,IClonable,IDisposable
- 11. 實現IDisposable的C#
- 12. 哪個更好,何時使用語句或在C#中的IDisposable上調用Dispose()?
- 13. 通過繼承使用IDisposable
- 14. 接口使用了IDisposable
- 15. 實施和使用IDisposable的
- 16. C#中的IDisposable接口#
- 17. 在使用塊中使用'作爲IDisposable'
- 18. C++ Ref類不是System :: IDisposable的成員;麻煩實施IDisposable
- 19. IntPtr,SafeHandle和HandleRef - 解釋
- 20. 帶內存壓力的SafeHandle
- 21. SafeHandle中invalidHandleValue的用途是什麼?
- 22. C#的LINQ到SQL - 如果DataContext的使用IDisposable的
- 23. 在使用塊或使用塊聲明中聲明IDisposable成員的區別?
- 24. 使用C或C++
- 25. IDisposable Winform
- 26. Impementing IDisposable
- 27. IDisposable鏈
- 28. 我可以使用SafeHandle而不是IntPtr嗎?
- 29. 我應該使用什麼SafeHandle實現進程句柄?
- 30. 哪裏不使用IDisposable實現?
用於* what *,究竟是什麼? –
使用什麼,確切地說。我不知道現在應該在什麼情況下使用哪一種看起來相似的結構。 –
@HansPassant在閱讀關於如何實現IDisposable的MSDN文章時,Microsoft提供了兩個如何實現該選項的選項。一個是實現一個終結器,並推薦使用一個SafeHandle。這確實有點混亂和誤導,所以我可以很好地理解OP的問題。 URL:http://msdn.microsoft.com/en-us/en-en/library/fs2xkftw%28v=vs.110%29.aspx 該網站使聲音非常通用,所以我第一次嘗試讓我的妥善處理的鋼筆物件也採用了SafeHandle,但效率不高。 – Tom