2009-10-15 7 views
6

W programie VB.NET tworzę nowy obraz bitmapowy, następnie wywoływam Graphics.FromImage, aby pobrać obiekt graficzny do rysowania na mapie bitowej. Obraz jest następnie wyświetlany użytkownikowi.Czy muszę wywołać Graphics.Dispose()?

Wszystkie przykłady kodu, które widziałem, zawsze wywołują .Dispose() na bitmapach i obiektach graficznych, ale czy jest taka potrzeba, gdy żadne z nich nie dotknęło plików na dysku? Czy są jakieś inne niezarządzane zasoby, które te obiekty mogły zdobyć, które nie zostałyby usunięte przez odśmiecacz?

Odpowiedz

5

Tak.

Zawsze wywołuj Dispose() na każdym obiekcie, który implementuje IDisposable. Uchwyty GDI używane przez obiekty graficzne są niezarządzane i wymagają utylizacji po ich zakończeniu.

Najlepsza praktyka polega na zamknięciu bloku using. Było kilka pytań SO na ten temat, BTW.

+0

Przepraszam, jeśli to jest duplikat. Nie widziałem niczego, co wiązałoby się z tą konkretną sprawą i byłem ciekawy, jakie (jeśli jakiekolwiek) zasoby niezarządzane zostaną użyte w tym przypadku. – alnorth29

1

Tak, należy wywołać utylizację. Nie ma związku z dotykaniem dysku; jest to związane z używaniem zasobów niezarządzanych, które muszą zostać poprawnie zwrócone do systemu operacyjnego. W przypadku obiektu Graphics, zakładam, że przydziela uchwyty kontekstu urządzenia, które powinny zostać zwolnione, gdy nie są już potrzebne.

6

Owiń w za pomocą oświadczenia dla zakresu, w którym jest to potrzebne. Więc nie martw się o jawne wywołanie Dispose()

Pseudokod:

using(new Graphics() = Graphics.FromImage) 
{ 
    //Magic happens... 
} 
1

Reguła z Dispose() to, że po utworzeniu obiektu, który jest IDisposable, to mają to nazwać. Najlepszym sposobem jest blok using lub finally.

Możliwe, że nie musiałeś tego robić, ale Dispose() zdecyduje o tym.

Jeśli masz obiekt, ale nie zadzwoniłeś do konstruktora, musisz sprawdzić dokumentację metody, która go zwróciła, aby sprawdzić, czy oczekuje on wywołania Dispose(), czy też będzie.

+0

Mówiąc dokładniej, właściwe użycie 'use' (zobacz inne odpowiedzi) niejawnie robi" Dispose ", więc nie musisz tego robić sam. – ToolmakerSteve

0

Graphics implements IDisposable, powinieneś więc zadzwonić do Dispose, aby zapewnić czyszczenie zasobów niezarządzanych.

Zasoby niezarządzane nie są obsługiwane przez garbage collector, więc muszą być obsługiwane ręcznie. Zwykle odbywa się to za pomocą metody Dispose() w celu zapewnienia czyszczenia w dobrze zdefiniowanym momencie. Może być również obsługiwane przez finalizatora, ale w takim przypadku zasób (zasoby) będzie w użyciu dłużej niż to konieczne.

Najprostszym sposobem zapewnienia wywołania w każdym przypadku jest użycie konstruktu używającego. Na przykład.

using(var g = Graphics.FromImage()) { 
    // use the resource 
} 
+0

"muszą być obsługiwane ręcznie" nie jest ściśle prawdą, ponieważ napisałeś nieco później. Właściwa implementacja 'IDisposable' powinna zapewnić bezpieczeństwo nawet bez ręcznego (w kodzie) wyrzucania. –

+0

@MaciejDopieralski: Rozważałbym wszystko, co musisz napisać, aby być ręcznym procesem.Jeśli zapomnisz zadzwonić Dispose clean up nie odbędzie się. Z kolei gromadzenie zarządzanych obiektów odbywa się automatycznie. –

+0

Jeśli mówisz o własnych klasach, to tak, ale wszystkie klasy "IDisposable" środowiska .NET zostaną usunięte wcześniej lub później, nawet jeśli nie wywołasz komendy "Dispose" w kodzie. –