Вам нужно вызвать Flush () в потоке или записи, если вы используете оператор using?

Я не уверен, нужно ли мне вызывать Flush() для используемых объектов, если я напишу что-то вроде этого:

using (FileStream...)
using (CryptoStream...)
using (BinaryWriter...)
{
    // do something
}

Они всегда автоматически смываются? Когда инструкция using сбрасывает их, а когда нет (если такое может случиться)?


person Ben    schedule 10.10.2011    source источник


Ответы (2)


Как только вы покидаете область видимости блока using, поток закрывается и удаляется. Close () вызывает Flush (), поэтому вам не нужно вызывать его вручную.

person Davide Piras    schedule 10.10.2011
comment
конец использования звонков близко? Я знаю только то, что он удаляет поток, и я каждый раз в конце вызываю метод закрытия. - person Felix C; 10.10.2011
comment
В этом нет необходимости, Dispose всегда будет закрывать поток, а Close сначала очищает поток. - person nos; 10.10.2011
comment
@FelixCzylwik: если бы конец использования не вызвал Close, у вас было бы множество открытых потоков и открытых SQLConnections там ...: D - person Davide Piras; 10.10.2011
comment
Я всегда закрывал их вручную перед окончанием использования ;-) - person Felix C; 10.10.2011
comment
@FelixC Многие вещи, которые компилятору не нужны, по-прежнему помогают в поисках удобочитаемости. - person Robino; 10.06.2015
comment
Связано: Всегда ли Stream.Dispose вызывает Stream.Close и предостережение о том, что неявный сброс является обычным поведением и не реализуется самим классом Stream (поэтому будьте осторожны при его расширении). - person Palec; 21.10.2015
comment
@Robino - Раньше я вручную добавлял close(), рассуждая аналогично вам. Проблема с этим была в большом проекте, иногда я или другой программист не помещали закрывающее заявление. Затем это привело к неуверенности в том, нужно ли туда добавлять близкие. Хуже того, иногда программист чувствовал, что ему нужно сделать flush, а затем close. В итоге я удалил все строки flush и close(), где они не были нужны. Последовательное кодирование и знание того, как работает система (использование подразумевает Dispose, подразумевает, что Close подразумевает Flush) также являются частью удобочитаемости. - person ToolmakerSteve; 08.10.2016

Это варьируется, Stream по умолчанию не вызывает Flush() в методе Dispose за некоторыми исключениями, такими как FileStream. Причина этого в том, что некоторым объектам потока не нужен вызов Flush, поскольку они не используют буфер. Некоторые, такие как MemoryStream, явно переопределяют метод, чтобы гарантировать, что никаких действий не будет предпринято (что делает его бездействующим).
Это означает, что если вы не хотите, чтобы дополнительный вызов был там, вам следует проверить, Stream подкласс, который вы используете, реализует вызов в методе Dispose, независимо от того, нужен он или нет.

Тем не менее, может быть хорошей идеей все равно назвать его просто для удобства чтения - аналогично тому, как некоторые люди вызывают Close() в конце своих операторов using:

using (FileStream fS = new FileStream(params))
using (CryptoStream cS = new CryptoStream(params))
using (BinaryWriter bW = new BinaryWriter(params))
{
    doStuff();
    //from here it's just readability/assurance that things are properly flushed.
    bW.Flush();
    bW.Close();
    cS.Flush();
    cS.Close();
    fS.Flush();
    fS.Close();
}
person TheHitchenator    schedule 23.01.2018
comment
Я бы сказал, что добавление вызовов сброса и закрытия активно вредит удобочитаемости и удобству обслуживания. Оператор using - это то, что дает уверенность в том, что объект правильно удален, даже в случае возникновения исключения. - person Palec; 23.01.2018
comment
@Palec Я понимаю эту позицию, это своего рода стандарт, разделяющий многих разработчиков по сравнению с тем, что я видел. - person TheHitchenator; 23.01.2018
comment
@Palec Кроме того, как указано в моем ответе, потоки по умолчанию не вызывают Flush() в своих методах удаления, что означает, что если вы используете нестандартный поток, созданный кем-то, кто не учел, тогда оператор using не будет сброшен буфер правильно. Из-за этого я бы сказал, что это хорошая практика - вручную сбрасывать - он ничего не сделает, если он не нужен, но если это так, он обеспечит правильное удаление буферов. - person TheHitchenator; 23.01.2018