Mam następujący kod
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
dispose()
Metoda jest wywoływana na końcu using
zestawienia szelki }
prawda? Skoro ja return
przed końcem using
oświadczenia, czy MemoryStream
przedmiot zostanie zutylizowany prawidłowo? co się tutaj stało?
Odpowiedzi:
Tak,
Dispose
zostanie wezwany. Jest wywoływana, gdy tylko wykonanie opuści zakresusing
bloku, niezależnie od tego, jakie środki zajęło opuszczenie bloku, czy to koniec wykonywania bloku,return
instrukcja czy wyjątek.Jak słusznie zauważa @Noldorin, użycie
using
bloku w kodzie zostaje wkompilowane dotry
/finally
, zDispose
wywołaniem wfinally
bloku. Na przykład następujący kod:skutecznie staje się:
Tak więc, ponieważ
finally
jest gwarantowane wykonanie potry
zakończeniu wykonywania bloku, niezależnie od jego ścieżki wykonania,Dispose
gwarantuje się wywołanie, bez względu na wszystko.Aby uzyskać więcej informacji, zobacz ten artykuł MSDN .
Dodatek:
tylko małe zastrzeżenie do dodania: ponieważ
Dispose
gwarantowane jest wywołanie, prawie zawsze dobrym pomysłem jest upewnienie się, żeDispose
nigdy nie zgłasza wyjątku podczas implementacjiIDisposable
. Niestety, w podstawowej bibliotece znajdują się klasy, które w pewnych okolicznościachDispose
są wywoływane - patrzę na Ciebie, odwołanie do usługi WCF / serwer proxy! - a kiedy tak się stanie, może być bardzo trudno wyśledzić oryginalny wyjątek, jeśliDispose
został wywołany podczas rozwijania stosu wyjątków, ponieważ oryginalny wyjątek zostaje połknięty na rzecz nowego wyjątku wygenerowanego przezDispose
wywołanie. To może być irytujące. A może to frustrujące i denerwujące? Jeden z dwóch. Może obydwa.źródło
Dispose
w końcu, więc skutecznie pracuje nad implementacjąfinally
, jak opisujesz.using
instrukcje zachowują się dokładnie jaktry ... finally
bloki, więc zawsze będą wykonywane na dowolnej ścieżce wyjścia kodu. Uważam jednak, że są one przedmiotem bardzo nielicznych i rzadkich sytuacji, w którychfinally
bloki nie są wywoływane. Przykładem, który pamiętam, jest wyjście z wątku pierwszego planu, gdy wątki w tle są aktywne: wszystkie wątki poza GC są wstrzymane, co oznacza, żefinally
bloki nie są uruchamiane.Oczywista zmiana: zachowują się tak samo, z wyjątkiem logiki, która pozwala im obsługiwać obiekty IDisposable, d'oh.
Dodatkowa zawartość: można je łączyć (w przypadku różnych typów):
A także rozdzielany przecinkami (gdzie typy są takie same):
źródło
Twój obiekt MemoryStream zostanie prawidłowo usunięty, nie musisz się tym martwić.
źródło
Wraz z
using
instrukcją obiekt zostanie usunięty niezależnie od ścieżki ukończenia.Czytaj dalej ...
źródło
Po skompilowaniu spójrz na swój kod w reflektorze. Przekonasz się, że kompilator refaktoryzuje kod, aby upewnić się, że metoda dispose jest wywoływana w strumieniu.
źródło