2010-03-01 17 views
15

Czy zawsze konieczne jest zamknięcie strumieni lub, ponieważ .net jest zarządzanym kodem, zostanie automatycznie zamknięty, gdy tylko wykracza poza zakres (zakładając, że nie zgłoszono żadnych wyjątków).Zamykanie strumieni, zawsze konieczne? .net

Illustrated:

static string SerialiseObjectToBase64(object obj) 
{ 
    var mstream = new MemoryStream(); 
    ... 
    return Convert.ToBase64String(mstream.ToArray());   
} 

jest dopuszczalne powyższy kod?

Odpowiedz

12

Z MemoryStream to jest trochę punkt sporny - ponieważ są ostatecznie rozmowy z zarządzanego byte[] (tak jest nadal zamierza czekać do rutynowego zbierania śmieci). Ale w ogólnie:, tak: powinieneś zamknąć (lepiej: Dispose() przez using, więc zostanie wyłączony po wyjściu wyjątku) po zakończeniu strumienia, w przeciwnym razie możesz nie spłukać niektórych danych do podstawowego (niezarządzanego) miejsca docelowego. Istnieją też strumienie, które nie są w pełni "przepłukiwane" napotrzeby, aby je uzyskać (szczególnie strumienie kompresji).

9

Dobrą praktyką jest zamykanie strumieni. Użyj instrukcji using i wywołaj ją, gdy znajdzie się poza zakresem (lub jeśli zostanie zgłoszony wyjątek), co spowoduje zamknięcie strumienia.

static string SerialiseObjectToBase64(object obj) 
{ 
    using (var mstream = new MemoryStream()) 
    { 
     ... 
     return Convert.ToBase64String(mstream.ToArray()); 
    } 
} 
+1

@Greg - Z pewnością zamknie się automatycznie po uruchomieniu finalizatora. Jednak nie ma gwarancji, GDY zamknie się (może być, gdy proces się zakończy) - tak jak wskazujesz, używanie "używania" jest zawsze dobrym pomysłem. – Aaron

+0

@Aaron - Dzięki, zaktualizowałem swoją odpowiedź. – Greg

3

.GNet GC jest bardzo ... leniwy. Tylko dlatego, że odniesienie zostało utracone, nie oznacza, że ​​natychmiast jest zmieciony, zmiażdżony i wysłany na składowisko. Zawsze dobrze jest zamykać otwarte zasoby i pozbywać się obiektów, które implementują IDisposable z tego właśnie powodu.

4

Zamknięcie strumieni i utylizacja obiektów to dwie różne rzeczy. Zamykanie strumieni powoduje opróżnienie bufora zapisu i zapisuje wszystkie niepisane dane do strumienia. Utylizacja strumienia po prostu zwolni pamięć używaną przez zmienną strumienia.

+3

To jest nieprawidłowe. Utylizacja strumienia * * zostanie zamknięta i przepłukana ... ale * nie zwolni * żadnej pamięci. –