Tôi đã đọc rất nhiều về finalizer và IDisposable
trong C#. Khi tôi cuối cùng đã trở nên rõ ràng từ sự nhầm lẫn quái dị này trên finalizer và IDisposable
, đột nhiên, ra khỏi hư không, có điều SafeHandle này. Niềm tin của tôi hoàn toàn bị lung lay trở lại. Tôi phải sử dụng cái gì?C# sử dụng IDisposable hoặc SafeHandle?
Trả lời
SafeHandle chỉ hữu ích khi xử lý các cuộc gọi Interop Interop. Trong Win32, hầu hết mọi thứ được đại diện bởi "xử lý". Điều này bao gồm Windows, Mutexes, vv Vì vậy, NET SafeHandle sử dụng mẫu dùng một lần để đảm bảo xử lý Win32 được đóng đúng cách.
Vì vậy, nếu bạn đang sử dụng các cuộc gọi Interop Inter32 và nhận lại các điều khiển Win32, hãy sử dụng SafeHandle. Đối với các đối tượng của riêng bạn, bạn sẽ gắn bó với IDisposable và finalizer.
Nhưng toàn bộ điểm của [IDisposable] (https://msdn.microsoft.com/en-us/library/system.idisposable (v = vs.110) .aspx), là để giải phóng * tài nguyên không được quản lý *, không nó? "đối tượng của riêng bạn" không rõ ràng, vì đối tượng có thể đại diện cho cả đối tượng được quản lý * và * không được quản lý, và kể từ đó, bạn là nhà phát triển, có thể phát triển cả mã bị cấm và không được quản lý và gọi mã không được quản lý từ mã được quản lý của bạn cũng bị mờ. –
@zespri - Nếu bạn quyết định triển khai IDisposable, điều đó ngụ ý rằng bạn đang duy trì lớp/đối tượng (nghĩa là đó là của bạn). Nếu đó là một đối tượng từ thư viện của bên thứ ba, thì bạn không thể triển khai IDisposable (nghĩa là nó không phải của bạn). Tôi không đề cập đến những gì cần được xử lý, cũng như bạn sẽ không triển khai IDisposable trong mã không được quản lý. – CodeNaked
Nhưng nếu đó là một đối tượng từ thư viện của bên thứ ba (được quản lý), bạn cũng không thể thực hiện 'SafeHandle'?Chỉ vì bạn có khả năng không có bất kỳ tầm nhìn trực tiếp nào của tay cầm ở nơi đầu tiên? Xin lỗi, không phải là chiến đấu, chỉ cố gắng hiểu ý bạn là gì. –
Bạn có thể/nên sử dụng SafeHandle cho bất kỳ tài nguyên không được quản lý nào có thể được biểu diễn dưới dạng IntPtr, tức là xử lý Win32, bộ nhớ được cấp bởi mã không được quản lý và cứ thế. Khi SafeHandle không phù hợp, nhưng bạn vẫn cần xử lý các tài nguyên không được quản lý, hãy cân nhắc tạo lớp giống như SafeHandle của bạn kế thừa từ CriticalFinalizerObject.
Trong tất cả các trường hợp khác (tức là xử lý tài nguyên được quản lý), hãy triển khai IDisposable. Trong hầu hết các trường hợp, bạn sẽ không cần finalizer, hầu hết các tài nguyên được quản lý sẽ không có sẵn khi finalizer được gọi, vì vậy sẽ không có gì để làm ở đó.
Trong hầu hết các trường hợp, lời khuyên của tôi là giả vờ rằng không có thứ gì như finalizer, nhưng chắc chắn 100% rằng bất kỳ đối tượng IDisposable nào được tạo sẽ bị hủy. Thậm chí nếu finalizers được viết 100% tối ưu, mã phân phối một nửa đối tượng của nó đúng và cho phép finalizers xử lý một nửa khác sẽ không được tốt như mã mà disposes của tất cả các đối tượng của nó đúng và không sử dụng finalizers. Mặc dù tác động hiệu suất từ finalizers mà không bao giờ chạy thường không quá khủng khiếp, finalizers rất khó để viết chính xác, họ có thể gây ra Heisenbugs nếu mã của họ hoặc mã tiêu thụ chúng không được viết hoàn hảo. Hơn nữa, việc thực hiện thành công finalizers thường sẽ yêu cầu tạo ra một hoặc nhiều WeakHandles mà chỉ có mục đích là để hỗ trợ hoàn thiện.
Có lẽ mạng lưới an toàn hoàn thành đáng giá, nhưng chi phí có thể đáng kể và mạng lưới an toàn không đáng tin cậy như người ta có thể muốn.
- 1. C# IDisposable Sử dụng: Thực hành tốt nhất
- 2. Tôi có thể sử dụng SafeHandle thay vì IntPtr không?
- 3. Điều nào tốt hơn và khi nào: sử dụng câu lệnh hoặc gọi Dispose() trên IDisposable trong C#?
- 4. Nơi đặt thử/nắm bắt khi sử dụng IDisposable
- 5. Khai báo IDisposable cho lớp hoặc giao diện?
- 6. Autofac và IDisposable interface
- 7. Xử lý iDisposable trong initializer thất bại hoặc constructor
- 8. Chuỗi IDisposable
- 9. C++: Sử dụng tự động hoặc typedef?
- 10. sử dụng (IDisposable obj = new ...) trong C# để viết các khối mã trong luồng (ví dụ: XML)
- 11. IDisposable là gì?
- 12. IDisposable Câu hỏi
- 13. Có quy tắc FxCop cho IDisposable được sử dụng cục bộ không?
- 14. Nên có thể sử dụng được như là tương đương Java cho .NET's IDisposable?
- 15. IDisposable trên một kho tiêm
- 16. Trả về KeyValuePair hoặc sử dụng biến trong C#?
- 17. Sử dụng giao thức RTMP hoặc RTSP trong C#
- 18. Có danh sách đối tượng chung nào triển khai IDisposable cho câu lệnh sử dụng không?
- 19. Singleton với finalizer nhưng không IDisposable
- 20. Sử dụng diễn viên là hai lần hoặc sử dụng như một lần và tạo một biến mới
- 21. Để sử dụng dịch vụ web truyền thống hoặc sử dụng WCF trong VS2008/C#
- 22. IDisposable, ObjectDisposedException, và các loại an toàn
- 23. thực hiện IDisposable đúng cho mã này
- 24. Đơn vị công việc, kho và IDisposable
- 25. Làm cách nào để cấu trúc ứng dụng giao diện điều khiển C# để sử dụng hiệu quả tài nguyên cơ sở dữ liệu IDisposable?
- 26. C# LINQ-to-SQL - Nên DataContext được xử lý bằng IDisposable
- 27. IDisposable: là cần thiết để kiểm tra null vào cuối {}?
- 28. Phiên chứa các mục thực hiện IDisposable
- 29. ClientBase không triển khai thành viên IDisposable
- 30. Sử dụng thư viện c/C++ sử dụng mạng cho mục tiêu ứng dụng iphone c
Sử dụng cho * what *, chính xác? –
Sử dụng cho những gì, chính xác. Tôi không biết tôi nên sử dụng cái nào trong tình huống hiện tại vì có 2 cấu trúc tương tự như vậy. –
@HansPassant Khi đọc bài đăng MSDN về cách triển khai IDisposable, Microsoft trình bày hai tùy chọn cách thực hiện điều đó. Một người đang triển khai trình hoàn thiện và người được khuyến nghị đang sử dụng SafeHandle. Nó thực sự là một chút khó hiểu và gây nhầm lẫn, vì vậy tôi có thể hiểu câu hỏi của OP rất tốt. URL: http://msdn.microsoft.com/en-us/en-en/library/fs2xkftw%28v=vs.110%29.aspx Trang web làm cho âm thanh rất chung chung, vì vậy lần đầu tiên tôi thử tải Các đối tượng bút được xử lý đúng cách cũng là với SafeHandle, vốn không hiệu quả lắm. – Tom