Czytałem dużo o finalizatorze i IDisposable
w języku C#. Kiedy w końcu staję się jasny z powodu tego potwornego zamieszania nad finalizatorem i IDisposable
, nagle, znikąd, pojawia się ta sprawa SafeHandle. Moja wiara znów jest całkowicie wstrząśnięta. Co mam użyć?C# use IDisposable lub SafeHandle?
Odpowiedz
SafeHandle jest przydatny tylko w przypadku wywołań Win32 Interop. W Win32 większość rzeczy jest reprezentowana przez "uchwyty". Obejmuje to system Windows, Mutexy itp. Dlatego też .NET SafeHandle używa wzorca jednorazowego użytku, aby zapewnić właściwe zamknięcie sterownika Win32.
Więc jeśli używasz wywołań Win32 Interop i odzyskujesz uchwyty Win32, użyj SafeHandle. Dla twoich własnych obiektów trzymasz się IDisposable i finalizatora.
Ale cały punkt [IDisposable] (https://msdn.microsoft.com/en-us/library/system.idisposable (v = vs.110) .aspx), to wydawanie * niezarządzanych * zasobów, nie jest to? "twoje własne obiekty" brzmi niejednoznacznie, ponieważ obiekt może reprezentować obiekt zarządzany * i * niezarządzany, a ponieważ programista może rozwijać zarówno kod zarządzany i niezarządzany, jak i wywoływać niezarządzany kod z zarządzanego kodu, twoja definicja "własnego" jest również rozmyte. –
@ zespri - Jeśli decydujesz się na wdrożenie IDisposable, oznacza to, że utrzymujesz klasę/obiekt (to znaczy twój). Jeśli jest to obiekt z biblioteki innej firmy, nie można zaimplementować IDisposable (tzn. Nie jest to Twoja). Nie mówię o tym, co powinno zostać usunięte, ani nie będziesz implementował IDisposable w niezarządzanym kodzie. – CodeNaked
Ale jeśli jest to obiekt z biblioteki innej firmy (zarządzanej), nie możesz zaimplementować 'SafeHandle'?Tylko dlatego, że i tak prawdopodobnie nie będziesz mieć żadnej bezpośredniej widoczności uchwytu? Przepraszam, nie jestem wojowniczy, tylko próbuję zrozumieć, co masz na myśli. –
Możesz/powinien używać SafeHandle dla dowolnego niezamanizowanego zasobu, który może być reprezentowany jako IntPtr, tzn. Win32 obsługuje, pamięć przydzielona przez niezarządzany kod i tak dalej. Kiedy SafeHandle nie jest odpowiedni, ale nadal musisz radzić sobie z niezarządzanymi źródłami, rozważ utworzenie własnej klasy przypominającej SafeHandle dziedziczącej po CriticalFinalizerObject.
We wszystkich innych przypadkach (tj. W zakresie zarządzania zasobami zarządzanymi) zaimplementuj IDisposable. W większości przypadków nie będziesz potrzebował finalizatora, większość zarządzanych zasobów będzie niedostępna po wywołaniu finalizatora, więc nie byłoby tam nic do zrobienia.
W większości przypadków moja rada byłaby udawaniem, że nie ma czegoś takiego jak finalizator, ale w 100% upewnia się, że wszelkie obiekty IDispozycyjne, które są tworzone, zostają zniszczone. Nawet jeśli finalizatory są napisane w 100% optymalnie, kod, który prawidłowo pozbywa się połowy swoich obiektów i pozwala finalizatorom obsługiwać drugą połowę, nie będzie tak dobry, jak kod, który poprawnie pozbywa się wszystkich obiektów i nie używa finalizatorów. Chociaż prawdą jest, że wpływ wykonawców, którzy nigdy nie działają, jest niezbyt straszny, finalizatorzy są trudni do napisania poprawnie, mogą spowodować, że Heisenbugs, jeśli ich kod lub kod, który je pochłonie, nie zostanie napisany idealnie. Ponadto, udana implementacja finalizatorów będzie często wymagać utworzenia jednej lub kilku Słabych Praw, których jedynym celem jest wsparcie finalizacji.
Być może zabezpieczenie przed sfinalizowaniem jest warte kosztów, ale koszt może być znaczny, a sieć bezpieczeństwa nie jest tak niezawodna, jak by się tego chciało.
- 1. Safehandle w języku C#
- 2. C# - ThreadPool QueueUserWorkItem Use?
- 3. C# IDisposable Using: Best Practice
- 4. Zadeklarować IDisposable dla klasy lub interfejsu?
- 5. laravel - use Klasa żądania lub klasa wejściowa
- 6. IDisposable chain
- 7. Wykrywanie "wyciekanych" obiektów IDisposable
- 8. Czy mogę używać SafeHandle zamiast IntPtr?
- 9. interfejs Autofac i IDisposable
- 10. Co jest lepsze, a kiedy: za pomocą instrukcji lub wywołanie Dispose() na IDisposable w C#?
- 11. Interruptor Interrupt use
- 12. iOS przy użyciu zmiennej instancji use lub metody getter
- 13. PHPUnit: Próbowanie @cover lub @use nie istniejącej metody
- 14. DI: Obsługa Life IDisposable Object
- 15. Czy muszę wdrożyć IDisposable na wszystkich klasach lub czy klasa podstawowa jest wystarczająca?
- 16. ArrayAdapter use Kotlin android
- 17. ClientBase nie implementuje IDisposable member
- 18. Pozbywanie się członków implementujących IDisposable
- 19. Dlaczego wątek nie implementuje IDisposable?
- 20. Implementacja IDisposable w zamkniętej klasie
- 21. Jednostka pracy, repozytoria i IDisposable
- 22. Typ odlewania do IDisposable - Dlaczego?
- 23. Coverity, Enumerable.Where (this ...) i IDisposable
- 24. GLES2.0 Use GL_TEXTURE_EXTERNAL_OES poprzez glEGLImageTargetTexture2DOES
- 25. Jak uczynić obiekt IDisposable zmienną klasy?
- 26. JavaScript 'use strict'; wewnątrz funkcji
- 27. Django REST Framework - CurrentUserDefault use
- 28. MapKit iOS 9 detailCalloutAccessoryView use
- 29. Python ReportLab use of splitfirst/splitlast
- 30. Czy można używać `use` w ten sposób?
Używaj dla * co *, dokładnie? –
Wykorzystaj do czego, dokładnie. Nie wiem, który powinienem użyć w jakiej sytuacji teraz, gdy są 2 takie pozornie podobne konstrukcje. –
@HansPassant Podczas czytania postu MSDN o tym, jak zaimplementować IDisposable, Microsoft przedstawia dwie opcje, jak to zaimplementować. Jedna implementuje finalizator, a zalecana używa SafeHandle. Jest to rzeczywiście nieco mylące i wprowadzające w błąd, więc bardzo dobrze rozumiem pytanie OP. URL: http://msdn.microsoft.com/en-us/en-en/library/fs2xkftw%28v=vs.110%29.aspx Witryna sprawia, że brzmi to bardzo ogólne, więc moja pierwsza próba uzyskania mojego Obiekty pióra odpowiednio rozmieszczone były również z SafeHandle, które nie było zbyt produktywne. – Tom