Зачем BinaryReader.Close закрывает underlying stream?
От: igna Россия  
Дата: 24.10.08 13:56
Оценка:
Обычно вместо

    using (var stream = new FileStream(path, FileMode.Open))
    using (var reader = new BinaryReader(stream, encoding))
        . . .


пишут

    using (var reader = new BinaryReader(new FileStream(path, FileMode.Open), encoding))
        . . .


расчитывая, что BinaryReader.Close закроет и FileStream.

А что если в конструкторе BinaryReader будет брошено исключение?
Re: Зачем BinaryReader.Close закрывает underlying stream?
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 24.10.08 13:59
Оценка:
Здравствуйте, igna, Вы писали:

BinaryReader/Writer втихую закрывает MemoryStream.
Автор: Odi$$ey
Дата: 23.01.07
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[2]: Зачем BinaryReader.Close закрывает underlying stream?
От: igna Россия  
Дата: 24.10.08 14:07
Оценка:
Здравствуйте, Odi$$ey, Вы писали:

OE>BinaryReader/Writer втихую закрывает MemoryStream.
Автор: Odi$$ey
Дата: 23.01.07


Спасибо, а что будет, если написать

    using (var reader = new BinaryReader(new FileStream(path, FileMode.Open), encoding))
        . . .


, а конструктор BinaryReader бросит исключение?
Re: Зачем BinaryReader.Close закрывает underlying stream?
От: _FRED_ Черногория
Дата: 24.10.08 14:16
Оценка:
Здравствуйте, igna, Вы писали:

I>расчитывая, что BinaryReader.Close закроет и FileStream.

I>А что если в конструкторе BinaryReader будет брошено исключение?

В данном случае это ответственность вызывающего кода. Стрим останется "висеть": что здесь "удивительного" и как, по твоему мнению, могло бы быть иначе?

З.Ы. Зачем спрашивать, когда прорить куда как быстрее?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[2]: Зачем BinaryReader.Close закрывает underlying stream?
От: igna Россия  
Дата: 24.10.08 14:44
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>В данном случае это ответственность вызывающего кода. Стрим останется "висеть": что здесь "удивительного" и как, по твоему мнению, могло бы быть иначе?


Аналогичное в C++ это типичная ошибка, но там об этом в книгах пишут (Sutter например), что так программировать неправильно, а в .NET сплошь и рядом примеры пытающиеся закрыть читатель (или писатель) и поток одним using-ом, что в книгах, что в MSDN.
Re[3]: Зачем BinaryReader.Close закрывает underlying stream?
От: _FRED_ Черногория
Дата: 24.10.08 17:03
Оценка:
Здравствуйте, igna, Вы писали:

_FR>>В данном случае это ответственность вызывающего кода. Стрим останется "висеть": что здесь "удивительного" и как, по твоему мнению, могло бы быть иначе?


I>Аналогичное в C++ это типичная ошибка, но там об этом в книгах пишут (Sutter например), что так программировать неправильно, а в .NET сплошь и рядом примеры пытающиеся закрыть читатель (или писатель) и поток одним using-ом, что в книгах, что в MSDN.


Что-то не понял Можно пример? Что является типичной ошибкой? "Как" это "неправильно"? Что за "прмиеры"?
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Зачем BinaryReader.Close закрывает underlying stream?
От: Константин Л.  
Дата: 24.10.08 18:23
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Odi$$ey, Вы писали:


OE>>BinaryReader/Writer втихую закрывает MemoryStream.
Автор: Odi$$ey
Дата: 23.01.07


I>Спасибо, а что будет, если написать


I>
I>    using (var reader = new BinaryReader(new FileStream(path, FileMode.Open), encoding))
I>        . . .
I>


I>, а конструктор BinaryReader бросит исключение?


Вообще, надо сказать, что disposable паттерн тот еще геморрой. Я для себя принял правило, что если объект ко мне пришел откуда-то, то dispose не звать. За вызов dispose должен отвечать код, который объект создал.
Re[4]: Зачем BinaryReader.Close закрывает underlying stream?
От: igna Россия  
Дата: 25.10.08 06:27
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Что-то не понял Можно пример? Что является типичной ошибкой? "Как" это "неправильно"? Что за "прмиеры"?


Не стопроцентный аналог, но тоже про утерянный ресурс:

Herb Sutter, More Exceptional C++, Item 20. An Unmanaged Pointer Problem, Part 1: Parameter Evaluation

А вот и пример из MSDN:

            BinaryReader binReader =
                new BinaryReader(File.Open(fileName, FileMode.Open));
            try
            {
                . . .
            }
            finally
            {
                binReader.Close();
            }


(http://msdn.microsoft.com/en-us/library/system.io.binaryreader.aspx)

Да, у этого конструктора BinaryReader нет параметра encoding, но для конструктора с параметром нет примера, потому первое, что приходит в голову, воспользоваться примером для конструктора без параметра, просто добавив последний:

            BinaryReader binReader =
                new BinaryReader(File.Open(fileName, FileMode.Open), encoding);
            try
            {
                . . .
            }
            finally
            {
                binReader.Close();
            }


А это уже точно (в общем случае) ошибка, поскольку encoding может оказаться равным null, конструктор BinaryReader бросит исключение и FileStream окажется бесхозным. Является ли ошибкой пример приведенный в MSDN, то есть возможно ли и здесь исключение в конструкторе, даже если File.Open вернул успешно сконструированный FileStream, не знаю, но спецификаций исключений в .NET нет, нет потому и никакой гарантии, что в следующей версии этот конструктор BinaryReader не начнет бросать еще какое-нибудь исключение, по этой причине думаю, что лучше самому закрывать FileStream:

            using (var fileStream = File.Open(fileName, FileMode.Open))
            using (var binReader = new BinaryReader(fileStream))
                . . .
Re[4]: Зачем BinaryReader.Close закрывает underlying stream?
От: igna Россия  
Дата: 25.10.08 06:31
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>Вообще, надо сказать, что disposable паттерн тот еще геморрой. Я для себя принял правило, что если объект ко мне пришел откуда-то, то dispose не звать. За вызов dispose должен отвечать код, который объект создал.


А что ты пишешь вместо этого?:

    using (var reader = new BinaryReader(new FileStream(path, FileMode.Open), encoding))
        . . .
Re[3]: Зачем BinaryReader.Close закрывает underlying stream?
От: TK Лес кывт.рф
Дата: 25.10.08 08:20
Оценка:
Здравствуйте, igna, Вы писали:

I>Аналогичное в C++ это типичная ошибка, но там об этом в книгах пишут (Sutter например), что так программировать неправильно, а в .NET сплошь и рядом примеры пытающиеся закрыть читатель (или писатель) и поток одним using-ом, что в книгах, что в MSDN.


Скорее всего это от того, что в c++ это действительно ошибка, а в .net — так, warning )
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[3]: Зачем BinaryReader.Close закрывает underlying stream?
От: MxKazan Португалия  
Дата: 25.10.08 08:31
Оценка: +1
Здравствуйте, igna, Вы писали:

I>Здравствуйте, _FRED_, Вы писали:


_FR>>В данном случае это ответственность вызывающего кода. Стрим останется "висеть": что здесь "удивительного" и как, по твоему мнению, могло бы быть иначе?


I>Аналогичное в C++ это типичная ошибка, но там об этом в книгах пишут (Sutter например), что так программировать неправильно, а в .NET сплошь и рядом примеры пытающиеся закрыть читатель (или писатель) и поток одним using-ом, что в книгах, что в MSDN.


Кстати, да. Вот из MSDN:

// Create a file and store the application settings.
public void Close()
{
    using(BinaryWriter binWriter =
        new BinaryWriter(File.Open(fileName, FileMode.Create)))
    {
        binWriter.Write(aspectRatio);
        binWriter.Write(lookupDir);
        binWriter.Write(autoSaveTime);
        binWriter.Write(showStatusBar);
    }
}


При этом в коде конструктора BinaryWriter мы видим, что он элементарно может бросить исключение, если поток не поддерживает запись.

Интересно, почему так
Re[4]: Зачем BinaryReader.Close закрывает underlying stream?
От: Константин Л.  
Дата: 25.10.08 09:33
Оценка: +1
Здравствуйте, MxKazan, Вы писали:

[]

примерам из msdn уже давно нельзя доверять.
Re[5]: Зачем BinaryReader.Close закрывает underlying stream?
От: Константин Л.  
Дата: 25.10.08 09:34
Оценка: 1 (1)
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Константин Л., Вы писали:


КЛ>>Вообще, надо сказать, что disposable паттерн тот еще геморрой. Я для себя принял правило, что если объект ко мне пришел откуда-то, то dispose не звать. За вызов dispose должен отвечать код, который объект создал.


I>А что ты пишешь вместо этого?:


I>
I>    using (var reader = new BinaryReader(new FileStream(path, FileMode.Open), encoding))
I>        . . .
I>


2 using'а
Re[4]: Зачем BinaryReader.Close закрывает underlying stream?
От: igna Россия  
Дата: 25.10.08 18:58
Оценка:
Здравствуйте, TK, Вы писали:

TK>Скорее всего это от того, что в c++ это действительно ошибка, а в .net — так, warning )


И что, утечки ресурса не будет?
Re[5]: Зачем BinaryReader.Close закрывает underlying stream?
От: _FRED_ Черногория
Дата: 26.10.08 09:48
Оценка:
Здравствуйте, igna, Вы писали:

_FR>>Что-то не понял Можно пример? Что является типичной ошибкой? "Как" это "неправильно"? Что за "прмиеры"?


I>А вот и пример из MSDN:

I>(http://msdn.microsoft.com/en-us/library/system.io.binaryreader.aspx)

Да, пример "не хороший". Написал бы им Content Bug прям в статье в MSDN.
Help will always be given at Hogwarts to those who ask for it.
Re[5]: Зачем BinaryReader.Close закрывает underlying stream?
От: chocho Россия  
Дата: 26.10.08 16:42
Оценка:
Здравствуйте, igna, Вы писали:

I>И что, утечки ресурса не будет?


Просто закрытие хэндла будет не детерминированое, а когда GC захочется...
"Не морочьте мне голову. Полыхаев" ©
Re[5]: Зачем BinaryReader.Close закрывает underlying stream?
От: _FRED_ Черногория
Дата: 27.10.08 06:59
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>примерам из msdn уже давно нельзя доверять.


Но с недавних пор появилась возможность сообщить об этом прямо на странице в "не хорошим" примером, чем и нужно пользоваться.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[6]: Зачем BinaryReader.Close закрывает underlying stream?
От: igna Россия  
Дата: 27.10.08 09:28
Оценка:
Здравствуйте, chocho, Вы писали:

C>Просто закрытие хэндла будет не детерминированое, а когда GC захочется...


Отчасти это еще хуже чем "детерминированое незакрытие" в C++, поскольку проблема может не выявится во время тестирования.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.