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

Как правильно использовать TcpClient ReadTimeout

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

Проблема заключается в том, что если вы используете свойство TcpClient ReadTimeout, и ваша операция чтения фактически истекает, Microsoft решила закрыть сокет. Этого не ожидается, не желательно, не сделанного с помощью какой-либо другой реализации сокета, о которой я знаю, и не имеет веской причины, что это должно быть иначе, чем ленивость программиста. Но это то, что Microsoft решила сделать.

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

В любом случае, по еще одному тангенциальному поиску я наткнулся на это старое сообщение в блоге:

http://blogs.msdn.com/b/mflasko/archive/2006/02/20/535655.aspx

Блоги MSDN > Блог Майка Фласко > Обработка таймаута при чтении сетевых данных

Ключ, который подскажет вам, как правильно обрабатывать таймауты чтения:

В этот момент может возникнуть соблазн поймать исключение, а затем переиздать чтение в том же сетевом потоке. Эта стратегия может привести к непредвиденным ошибкам. Самое лучшее, что нужно сделать, - теперь рассматривать NetworkStream (сокет) как находящееся в неустойчивом состоянии. Это происходит потому, что, когда базовый стек истекает, считывание базового ввода-вывода отменяется. Если данные поступают одновременно, данные будут потеряны, что приведет к повреждению потока данных.

и решение:

Лучше всего поймать исключение, закрыть сокет или TCPClient и, при необходимости, снова подключиться.

Хотя я все еще думаю, что это налагает ненужную нагрузку на пользователя API, по крайней мере, это самое правильное решение, которое я смог найти из десятков сайтов, на которых я смотрел, пытаясь понять, socket ReadTimeout.

Я надеюсь, что этот вопрос/комментарий спасет кого-то, сколько часов мне понадобилось, чтобы найти.

4b9b3361