2012-04-11 9 views
5

Na przykład mam metodęAutodisposing obiektów

SomeMethod(Graphics g) 
{ 
    ... 
} 

Jeśli będę wywołać tę metodę w sposób

SomeMethod(new Graphics()) 

Czy moje obiekt graficzny być autodisposed czy mam zadzwonić g.Dispose() ręcznie w końcu metoda?

SomeMethod(Graphics g) 
{ 
    ... 
    g.Dispose(); 
} 
+4

Oprócz "nie", twoja metoda powinna również * nie * być odpowiedzialna za wyrzucenie obiektu graficznego. Ważne jest, aby czas życia obiektów graficznych był zarządzany w jednym miejscu - co oznacza, że ​​należy go umieścić w tej samej klasie, która je utworzyła. Posiadanie obiektu w jakimś nieokreślonym miejscu w dół stosu wywołań sprawia, że ​​kod jest trudny do zrozumienia i utrzymania, i może łatwo doprowadzić do błędów później. – MattDavey

Odpowiedz

7

Jednorazowe przedmioty nie dostanie autodisposed (najbliżej można dostać się, że realizuje finalizatora który wywołuje Dispose razie potrzeby). Trzeba to zrobić ręcznie, dzwoniąc pod numer Dispose() lub używając go z blokiem using.

Jeśli chcesz auto zbyć przedmiot, można to zrobić:

using (var g = new Graphics()) { 
    SomeMethod(g); 
} 

bloku Using zapewnia, że ​​metoda Dispose() nazywa się automatycznie, jak tylko końcach bloku (tak w tym przypadku, po SomeMethod zwraca lub zgłasza wyjątek).

Uwaga: Obiekt należy zutylizować w miejscu w pobliżu, w którym został utworzony, o ile to możliwe. Zabranie ważnego przedmiotu i pozbycie się go w metodzie może spowodować zamieszanie.

Grafika i prawdopodobnie większość, jeśli nie wszystkie klasy BCL implementujące ten interfejs, będą również wywoływać Dispose() po wywołaniu Finalizera. Jest to częścią prawidłowej implementacji IDisposable. Jednak nigdy nie wiadomo, kiedy wywoływacz jest wywoływany i nie powinieneś polegać na tym szczególe implementacji, jeśli chcesz, aby obiekt był deterministycznie usuwany.

+1

W powyższym przykładzie, czy obiekt graficzny zostanie automatycznie zinterpretowany, czy nie? –

+0

No. Zobacz moją edycję. – Botz3000

+0

Czekaj, czy mówisz, że GC nie zadzwoni do "Dispose", gdy obiekt zostanie sfinalizowany? (Biorąc pod uwagę poprawną implementację 'IDisposable') – leppie

3

Należy prawdopodobnie używać using

using (var graphicsObject = new Graphics()) { 
    SomeMethod(graphicsObject); 
} 

Obiekt zostanie automatycznie umieszczona na końcu użyciu instrukcji, nawet jeśli wystąpi wyjątek.

2

Sprawdź Graphics Class

public sealed class Graphics : MarshalByRefObject, 
    IDeviceContext, IDisposable 

implementuje interfejs IDisposable, więc jeśli użyć instrukcji using z Obiektu Graficznego następnie zostanie ona automatycznie usuwane.

W przykładzie

SomeMethod(Graphics g) 
     { 
     ... 
     g.Dispose(); 
     } 

zostanie usunięte przy użyciu g.Dispose, ale najlepszym rozwiązaniem jest using stwierdzenie.

przykład:

using (Graphics g = this.CreateGraphics()) 
{ 
//Do some graphics operation. 
} 
4

Właściwa droga do pracy z jednorazowych przedmiotów jest zawinąć je w using bloków:

using (var g = new Graphics()) { 
    SomeMethod(g); 
} 

Kiedy wykonanie pozostawia blok usingGraphics jest prawidłowo umieszczony nawet jeśli wyjątek został zgłoszony.

Jednakże, jeśli nie wyrzucaj przedmiotu albo jawnie lub implicitely użyciu using blok przedmiotem nadal będzie się wyrzucać kiedy to śmieci zebrane (zakładając, że finalizator poprawnie nazywa Dispose jak powinien). Kiedy to się dzieje, nie masz kontroli i dlatego powinieneś upewnić się, że przedmioty jednorazowego użytku są odpowiednio rozmieszczone, gdy tylko przestaną być potrzebne do uwolnienia zasobów, do których roszczą przedmioty.

2

W swoim przykładzie nie powinieneś pozbywać się przedmiotu, który został ci przedstawiony jako argument. Nie jest to zalecane, ponieważ obiekt ten może być używany poza twoją metodą. Utylizacja obiektów użytkowych powinna (zwykle) odbywać się w tej samej metodzie, w której ją tworzysz. Wyjątek dla obiektów klasy lub obiektów stanu.

Tak jak w przypadku innych odpowiedzi, użyj using, aby utworzyć i wyrzucić obiekt. Jest to naprawdę wymagane tylko w przypadku obiektów wykorzystujących cenne zasoby, takie jak połączenie z bazą danych. Powiedziawszy, że zawsze powinieneś zadzwonić pod numer Dispose() (jawnie lub przez using), jeśli obiekt go implementuje, ponieważ oznacza to, że używa niezarządzanych lub dużych ilości zasobów.

Wszystkie obiekty .NET Framework, które nie będą wywoływać Dispose na (w żaden sposób) zostaną ostatecznie automatycznie rozpoznane przez Garbage Collector. Prawidłowe wdrożenie interfejsu IDisposable powinno mieć destruktor/finalizator, który wywołuje Dispose. Ma to na celu zapewnienie, że cenne zasoby nie zostaną utracone tylko z powodu złego kodu. Twoje zasoby zostaną wydane znacznie później, ale będą i to jest ważne. W ten sposób zaimplementowane są wszystkie klasy jednorazowe w .NET i jak wszystkie klasy powinny implementować IDisposable.

Kod powinien wyglądać następująco:

using(Graphics g = new Graphics()) 
{ 
    SomeMethod(g) 
    { 
     ... 
    } 
} 

Sprawdź this zaleceń Microsoftu na IDisposable.Dispose metody.

Powiązane problemy