Dispose vs Dispose (bool)

/ Align = "left" / Staram się, aby mój kod usuwał zasoby poprawnie. Tak więc ustawiałem moje klasy jako IDisposable (z metodą Disposable), upewniając się, że metoda Disposable zostanie wywołana.

Ale teraz FXCop mówi mi wiele rzeczy o Disposing = false i wywołaniu Dispose (false).

Nie widzę sposobu na pozbycie się boola. Czy muszę je zrobić? Jeśli tak, to dlaczego? Dlaczego po prostu nie mieć metody, która zostanie wywołana, gdy jest usuwanie?

Widziałem tu jakiś kod: http://msdn.microsoft.com/en-us/library/ms244737.aspx to pokazuje, jak zrobić metodę usuwania, która zajmuje bool. Mówi, że jest dla zasobów rodzimych vs zarządzanych. Ale myślałem, że chodzi tylko o niezarządzane zasoby.

Również linia, na którą FxCop narzeka jest następująca:

    ~OwnerDrawnPanel()
    {
        _font.Dispose();
    }

Jest napisane:

CA1063: Microsoft.Design: Modify ' OwnerDrawnPanel.~ OwnerDrawnPanel () ' tak, że wywołuje Dispose (false) a następnie zwraca.

Ale Font nie ma na nim Dispose (bool) (który mogę znaleźć).

Podsumowując:

Dlaczego potrzebuję Dispose (bool)? a jeśli tak, to dlaczego Font jej nie ma? a ponieważ go nie ma, dlaczego FXCop prosi mnie o jego użycie?


Dzięki za wszystkie świetne odpowiedzi. Myślę, że teraz rozumiem. Oto

Odpowiedź jaką widzę:

Utylizacja "niezarządzanych" zasobów dzieli się na dwie Kategorie:

  1. zasoby, które są zawinięte w zarządzaną klasę (np. bitmapę, czcionkę itp.), ale nadal muszą być wywołane, aby je poprawnie wyczyścić.
  2. Zasoby, które zostały przydzielone, które są reprezentacjami zasobów natywnych (tj. konteksty urządzeń, które muszą zostać zwolnione)]}

Dispose (bool) służy do rozróżnienia między tymi dwoma:

  1. gdy Dispose jest bezpośrednio wywoływany na Twoim obiekcie, chcesz uwolnić oba rodzaje " niezarządzanych" zasoby.
  2. kiedy twój obiekt jest gotowy do zbierania śmieci, nie musisz martwić się o pierwszy rodzaj zasobów. Śmieciarz zajmie się nimi, kiedy je wyczyści. Musisz tylko martwić się o prawdziwe zasoby natywne, które zostały przydzielone (jeśli w ogóle).
 31
Author: The Smallest, 2011-03-07

10 answers

IDisposable dostarcza metodę z podpisem

public void Dispose()

Najlepsze praktyki Microsoft ( http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx ) polecam wykonanie drugiej prywatnej metody z podpisem

private void Dispose(bool)

Twoja publiczna metoda usuwania i Finalizer powinny wywołać tę prywatną metodę usuwania, aby zapobiec wielokrotnemu usuwaniu zarządzanych zasobów.

Możesz naprawić Ostrzeżenie, które otrzymujesz, implementując IDisposable i usuwając obiekt font w metoda dispose, lub utworzenie metody Dispose(bool) w klasie i spraw, aby finalizer wywołał tę metodę.

 7
Author: Kyle Trauberman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-07 21:06:14

Dispose(bool) jest wzorcem do zaimplementowania Finalize i Dispose Do Czyszczenia niezarządzanych zasobów , Zobacz to po szczegóły

 8
Author: Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:07

Dispose(bool) nie ma być publicznie i dlatego nie widzisz go na Font.

W przypadku, gdy jakiś użytkownik z twojej klasy zapomni wywołać Dispose na Twojej metodzie, uwolnisz niezarządzane zasoby tylko , wykonując połączenie do Dispose(false) w Finalizer.

W przypadku, gdy IDispose jest poprawnie wywołane, wywołujesz Dispose na zarządzanych zasobach i również zajmij się niezarządzanymi.

Flaga ma na celu rozróżnienie tych dwóch przypadków.

Jest to wzór zalecany przez MSDN.

 7
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-07 21:06:08

FxCop mówi, że należy zaimplementować wzór jednorazowego użytku, jak opisano Tutaj . Zauważ, że powinieneś nie używać finalizerów do usuwania zarządzanych zasobów, takich jak _font is. Finalizery są używane do czyszczenia niezarządzanych zasobów. Jeśli nie wykonasz logiki czyszczenia w metodzie Dispose swojej (pod) klasy, zostaną one wykonane niedeterministycznie przez garbage collector.

 3
Author: m0sa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-07 21:13:33

Należy również pamiętać, że jest to bardzo rzadko , że trzeba cokolwiek zrobić w destruktorze. Regularnie o wszystko dba Śmieciarz. Na przykład w kodzie nie musisz usuwać _font obiektu w destruktorze OwnerDrawnPanel. Ponieważ panel jest czyszczony przez GC, więc będzie _font, ponieważ panel był jedynym, który odwołał się do niego, prawda?

Ogólnie rzecz biorąc, jeśli posiadasz przedmioty jednorazowego użytku, musisz je pozbywać tylko wtedy, gdy masz własne Dispose metoda została wywołana. Ale Nie w destruktorze. Kiedy Destruktor jest uruchomiony, możesz się założyć, że wszystkie zagregowane obiekty również są czyszczone.

 2
Author: Fyodor Soikin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-07 21:11:06

Prawie nigdy nie powinieneś używać finalizerów. Są one tylko dla klas, które bezpośrednio zawierają niezarządzane zasoby, a w. NET 2.0+ powinny być zawinięte w SafeHandle.

 2
Author: Mark Sowul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-07 21:11:39

Myślę, że Dispose(true) uwolni zarówno zarządzany, jak i niezarządzany zasób, ponieważ nie musimy ponownie wywoływać finalize, dlatego piszemy GC.SupressFinalize() Po Dispose(true).

Wywołujemy Dispose(false) w destruktorach, aby uwolnić niezarządzane zasoby i będziemy wywoływani przez Runtime, a nie kod użytkownika.

 2
Author: Ratnesh Sinha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-26 13:45:38

, Dispose(bool disposing) wzór jest również udokumentowany na MSDN . Nie rozróżnia się zasobów zarządzanych i niezarządzanych, ale to, czy {[1] } jest wywoływany przez Twój kod, czy przez runtime.

 1
Author: Ben Hoffstein,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-07 21:06:03

Znalazłem dobry artykuł o poprawnej implementacji interfejsu IDispose: http://msdn.microsoft.com/en-us/library/ms244737 (v=vs.80). aspx

 0
Author: OrahSoft,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-07 21:07:46

Wzorzec realizacji publicznego public void Dispose(), protected virtual void Dispose(bool), finalizery to najlepsza praktyka zalecana przez Microsoft jako sposób porządnego uporządkowania kodu czyszczenia zarówno dla zarządzanych, jak i niezarządzanych zasobów.

Zasadniczo kod, który używa Twojej Disposable klasy powinien wywołać Dispose(), ale jeśli tak się nie stanie, finalizator ~ClassName() zostanie wywołany przez Garbage Collection, i na podstawie tego, która z nich jest używana, ustawiasz argument na Dispose(bool) jako true lub false, a w Twoim Dispose(bool), czyścisz zarządzane zasoby tylko wtedy, gdy argument jest prawdziwy.

Ostrzeżenie, które otrzymujesz, wydaje się szczególnie zalecać użycie tej praktyki w swojej metodzie finalize ~ClassName().

 0
Author: Sam Skuce,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-07 21:40:08