2010-11-03 12 views
8

Kiedy przeczytałem kilka artykułów na temat zarządzania pamięcią w C#, byłem zdezorientowany przez metody Finalizer.Dobre przykłady użycia Finalizerów w C#

Istnieje wiele skomplikowanych zasad, które się z nimi wiążą. Na przykład, nikt nie wie kiedy wywoływacze zostaną wywołani, zadzwonili nawet jeśli kod w rzutach ctor, CLR nie gwarantuje, że wszystkie finalizatory będą wywoływane, gdy programy się wyłączy itp.

Do jakich finalizatorów można użyć w rzeczywistości życie?

Jedyny przykład, który znalazłem, to program, który generuje sygnał dźwiękowy po uruchomieniu GC.

Czy używasz Finalizerów w swoim kodzie i może mieć kilka dobrych próbek?

UPD:

finalizatory mogą być stosowane, gdy developpers chcesz się upewnić, że niektóre klasy zawsze umieszczona prawidłowo przez IDisposable. (link; Dzięki Steve Townsend)

+4

Tylko napisałem garść finalizatorów w ciągu ostatnich 5 lat projektów, nad którymi pracowałem i wszystkie były przeznaczone dla klas, które współpracowały ze starszym, niezarządzanym API. W normalnych warunkach finalizatory nigdy nie były wywoływane, ponieważ obiekty zostały usunięte, zanim zostały zakwalifikowane do zbierania śmieci, a finalizacja została wyraźnie zniesiona. –

+0

@Dan Bryant - tak - nie widziałem tego przed zrobieniem tego punktu, moja odpowiedź ... –

+1

Zawsze uważałem, że finalizatorzy byli w stanie zutylizować niezarządzane zasoby jako bezpieczne w razie awarii wywołania IDisposable.Dispose() (ktoś zapomniał użyć metody using() lub wreszcie) i nie powoduje żadnych problemów, o ile Twoja Dispose() wywołuje SuppressFinalize –

Odpowiedz

4

Istnieje wyczerpująca omówienia wykorzystania Finalizer z przykładów here. Link dzięki uprzejmości @SLaks pod numerem a related answer.

Zobacz także: here, aby uzyskać bardziej zwięzłe podsumowanie tego, kiedy go potrzebujesz (co jest "niezbyt często").

Jest fajna wcześniejsza odpowiedź here z innym dobrym przykładem z prawdziwego świata.

Podsumowując ze stosownego wyciągu:

potrzebne są

finalizatory zagwarantować uwalniania ograniczonych zasobów z powrotem do system operacyjny jak uchwyty plików, gniazd, obiektów jądra itp

Aby uzyskać więcej informacji o poprawnych przykładach rzeczywistych, przejrzyj klasę dotkniętą w .Net Framework to wyszukiwanie MSDN:

http://social.msdn.microsoft.com/Search/en-US?query=%22.Finalize%22&ac=8

jeden ważny powód, mogę myśleć, kiedy może trzeba użyć finalizator jest, jeśli owinąć innej firmy kodu natywnego API w zarządzanym opakowaniu i podstawowa natywne biblioteki kodu API wymaga terminowego uwalniania wykorzystane zasoby systemu operacyjnego.

3

Najlepsza znana mi praktyka jest prosta - nie używaj ich. Mogą jednak wystąpić przypadki narożne, gdy chcesz użyć finalizatora, szczególnie w przypadku obiektów niezarządzanych i nie możesz wdrożyć wzoru usuwania (nie mam problemów ze starszymi wersjami), wtedy możesz ostrożnie stosować metodę Finalize (i może to zmniejszyć wydajność twojego systemu, spraw, by twoje obiekty były nieumarłe i inne prawdopodobnie dziwne scenariusze, pamiętając o wyjątkach, ponieważ są one niepołączalne :)).

W 99% przypadków wystarczy napisać wzór "Wyrzuć" i użyć tej metody do czyszczenia po sobie i wszystko będzie dobrze.

+0

Nie rozumiem, o czym tu mówisz (możesz to trochę sformalizować), ale jestem w 100% pewien, że w 99% przypadków nie chcesz zbliżać się do finalizatorów. – annakata

+0

Dokładnie to mówię. Mogę edytować odpowiedź, jeśli nie jest to jasne. Finalizatorzy są niebezpieczni i wymagają dużej ostrożności przy ich wdrażaniu. I jak mówili przede mną ludzie, są oni potrzebni tylko wtedy, gdy mamy do czynienia z pewnymi niezarządzanymi zasobami. Jednak łączenie się ze starszą technologią lub używaniem bibliotek c/C++ może sankcjonować korzystanie z niej. – luckyluke

+0

Klasa powinna prawie nigdy nie mieć finalizatora, chyba że cel danej klasy kręci się wokół niej (jak np. W przypadku SafeHandle). Jeśli skomplikowany obiekt będzie wymagał wyłącznego użycia czegoś, co przeżyje, powinien stworzyć inny obiekt, którego jedynym celem jest zarządzanie tym rzeczem. Wiele komplikacji powstaje, gdy obiekt z finalizatorem zawiera odwołania do innych obiektów, które z kolei mogą zawierać odniesienia do innych obiektów itp. To ironiczne, że wzorzec Dispose zapewnia wyraźne wsparcie dla posiadania klasy pochodnej dodania finalizatora - wątpię, czy kiedykolwiek dobry pomysł. – supercat

Powiązane problemy