2010-12-16 9 views
16

Mam klasę, która zasadniczo opakowuje strumień do odczytu/zapisu, ale strumień ten będzie zarządzany przez konsumenta tej klasy. Dla ułatwienia użycia używam klas StreamReader i StreamWriter do wykonywania operacji we/wy w strumieniu. Normalnie otwieram czytnik i program piszący w blokach using, ale chcę uniknąć zamykania czytnika i programu piszącego, ponieważ spowoduje to również zamknięcie strumienia bazowego i muszę go zachować.Czy nie należy zamykać StreamReader/StreamWriter, aby utrzymać otwarty strumień?

Czy bezpieczne jest zarządzanie pamięcią/zasobami, aby nie zamykać StreamReader/StreamWriter, jeśli oczekuję, że bazowy strumień będzie zarządzany przez osobę dzwoniącą? Czy czytelnik i pisarz będą zbierać śmieci, gdy strumień zostanie jawnie zamknięty w innym miejscu?

public class Wrapper 
{ 
    private Stream _underlyingStream; 
    public Wrapper(Stream underlyingStream) 
    { 
     _underlyingStream = underlyingStream; 
    } 

    public string GetValue() 
    { 
     _underlyingStream.Seek(0, SeekOrigin.Begin); 
     var reader = new StreamReader(_underlyingStream); 
     return reader.ReadToEnd(); // we're done, but the stream is not ours to close 
    } 
} 
+2

To pytanie może pomóc: http://stackoverflow.com/questions/1862261/can-you-keep-a-readreader-from-disposing-the-basis-stream –

+1

Nie związane z pytaniem, ale ponieważ opakowanie nie "jest właścicielem" strumienia, możesz również zapisać oryginalny '_underlyingStream.Position' i przywróć go do tej pozycji po ReadToEnd() przed powrotem do wywołującego. (Chociaż twoje użycie może być takie, że rozmówca spodziewa się, że pozycja zostanie dotknięta takim wezwaniem - i może zapisać pozycję, jeśli to ma znaczenie.) –

Odpowiedz

5

Jeśli nikt nie zamknie strumieni, ostatecznie zostanie wywołany finalizator, który powinien wywołać funkcję usuwania i zamknąć je po GC. Ale to całkiem spora miara zasobów, ponieważ pozostawia wszelkie możliwe kosztowne zasoby przydzielone do GC. Może się to pogorszyć, im dłużej będzie żył obiekt, zwłaszcza jeśli przeżyje kolekcje, które mają awansować na gen 1 lub nawet 2.

To byłoby miłe, gdybyś mógł przedstawić coś swojemu rozmówcy, który to izoluje. Być może możesz cache coś ze strumienia, aby można go zamknąć, nadal wyświetlając zawartość dzwoniącemu?

EDYTOWANIE po edycji: Teraz, gdy widzę, że Twój rozmówca PRZESZUJE ci strumień do działania, moja odpowiedź musi być inna! Jest oczywiste, że Twój rozmówca powinien zarządzać czasem życia strumienia. Na początku miałem wrażenie, że twoja klasa stworzyła strumień i ma nadzieję, że to on zadzwonił.

0

To zdecydowanie nie jest w porządku. read this from msdn

Zamknięcie wywołuje metodę Dispose przekazującą wartość true. Płukanie strumienia nie spowoduje opróżnienia jego podstawowego kodera, chyba że wyraźnie wybierzesz opcję Zamknij.

Spróbuj hermetyzować wszystkie zamówienia w klasie.

+0

Nie całkiem to rozumiem. Dlaczego opróżnianie enkodera nie jest złe? Czy masz jakieś linki przydatne w tym, co to jest? –

+1

Spłukiwanie to jedno, ale irytujące jest to, że utylizacja owijki zawsze zrzuca strumień. Zazwyczaj chcesz uzyskać do niego dostęp z wyższego poziomu. – Nyerguds

Powiązane problemy