Подтвердить что ты не робот

Можно ли не закрыть StreamReader/StreamWriter, чтобы поддерживать открытый поток?

У меня есть класс, который по существу обертывает Stream для чтения/записи, но этот поток, как ожидается, будет управляться потребителем этого класса. Для простоты использования я использую классы StreamReader и StreamWriter для выполнения операций ввода-вывода в потоке. Обычно я бы обернул читателя и писателя в блоки using, но я хочу, чтобы не закрывать читателя и писателя, потому что это также закрывает базовый поток, и я должен держать его открытым.

Безопасно ли с точки зрения управления памятью/ресурсами не закрывать StreamReader/StreamWriter, если я ожидаю, что управляющий поток будет управляться вызывающим? Будет ли сборщик и писатель собирать мусор, когда поток явно закрыт в другом месте?

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
    }
}
4b9b3361

Ответ 1

Если никто не закрывает потоки, то в конечном итоге будет вызываться финализатор, который должен вызывать dispose и закрывать их при GC. Но это довольно дерьмо-ресурс, потому что он оставляет любые, возможно, дорогостоящие ресурсы, выделенные до GC. Это может ухудшиться, чем дольше будет жить ваш объект, особенно если он выживет в коллекциях, чтобы повысить их до 1 или даже 2.

Конечно, было бы неплохо, если бы вы могли представить что-то своему вызывающему, которое изолирует это. Возможно, вы можете кэшировать что-то из потока, чтобы вы могли закрыть его, продолжая показывать контент своему абоненту?

ИЗМЕНИТЬ после вашего редактирования: теперь, когда я вижу, что ваш вызывающий абонент прогоняет поток, на который нужно работать, мой ответ должен быть другим! Очень ясно, что ваш вызывающий абонент должен управлять потоком жизни. Сначала у меня сложилось впечатление, что ваш класс создал поток и надеялся, что вызывающий абонент справился с ним.

Ответ 3

Это определенно не нормально. прочитать это из msdn

Закрытие вызывает метод Dispose, передающий истинное значение. Промывка потока не будет очищать его базовый кодер, если вы явно не вызовете Close.

Попробуйте инкапсулировать все IO в классе.