На практике при использовании StreamReader
это может произойти только с потоком, который может задерживаться на некоторое время - например, с сетевым потоком, как люди упоминали здесь.
Однако с TextReader
как правило, вы можете ожидать, что это произойдет в любое время (в том числе, возможно, с будущей версией .NET в случае, если это в настоящее время не происходит - что это не произойдет с StreamReader
на FileStream
isn ').документально подтверждено, поэтому нет гарантии, что это не произойдет в будущем.
В частности, во многих случаях это проще (с эффектом более простого, более надежного и, вероятно, более эффективного кода).) для разработчиков не возвращать запрошенную сумму, если они могут частично выполнить вызов, просто опустошив текущий буфер, или используя запрошенную сумму в качестве суммы для передачи в источник поддержки (поток или другой TextReader
) перед выполнениемоперация, которая может возвращать только меньшее количество символов.
Теперь, чтобы ответить на реальный вопрос относительно «Когда тo использовать StreamReader.ReadBlock ()? "(или, в более общем случае, когда использовать TextReader.ReadBlock ()).Необходимо иметь в виду следующее:
Оба Read()
и ReadBlock()
гарантированно вернут хотя бы один символ, если не был прочитан весь источник.Ни один из них не вернет 0, если имеется ожидающее содержимое.
Вызов ReadBlock()
, когда Read()
сделает, бесполезно, так как он повторяется без необходимости.
Но, с другой стороны, это не , что расточительно.
Но, с другой стороны, случаи, когда Read()
вернет меньше запрошенных символов, часто бываютв случаях, когда другой поток занимается получением контента, который будет заполнять буфер для следующего вызова, или когда этот контент еще не существует (например, пользовательский ввод или ожидающая операция на другом компьютере) - в этом случае лучший общий параллелизм можно найти вобработка частичного результата, а затем повторный вызов Read()
, когда он закончится.
Итак.Если вы можете сделать что-то полезное с частичным результатом, тогда позвоните Read()
и поработайте над тем, что вы получите.В частности, если вы просматриваете и работаете с результатом каждого Read()
, тогда делайте это, а не с ReadBlock()
.
. Известный случай, если вы создаете свой собственный TextReader, который поддерживается другим.Нет смысла вызывать ReadBlock()
, если алгоритму действительно не нужно определенное количество символов для работы - просто верните столько, сколько вы можете из вызова на Read()
и позвольте вызывающему коду позвонить ReadBlock()
, если это необходимо.
В частности, обратите внимание, что следующий код:
char buffer = char[4096];
int len = 0;
while((len = tr.ReadBlock(buffer, 0 , 4096)) != 0)
DoSomething(buffer, 0, len);
Может быть переписан как:
char buffer = char[4096];
for(int len = tr.Read(buffer, 0, 4096); len != 0; len = tr.Read(buffer, 0, 4096))
DoSomething(buffer, 0, len);
Иногда он может вызывать DoSomething()
с меньшими размерами, но можеттакже обеспечьте лучший параллелизм, если есть другой поток, предоставляющий данные для следующего вызова Read()
.
Однако в большинстве случаев выигрыш незначителен.Если вам действительно нужно определенное количество символов, тогда звоните ReadBlock()
.Наиболее важно в тех случаях, когда Read()
будет иметь тот же результат, что и ReadBlock()
, накладные расходы на ReadBlock()
, проверяющие, что это так, очень незначительные Не пытайтесь угадать, является ли Read()
безопасным или нет в данном случае;если требуется гарантия ReadBlock()
, используйте ReadBlock()
.