Корректировка тайм-аута соединения HttpWebRequest в C#

Сравнения производительности между типами соединений не важны, поскольку они дают наборы результатов differnt. Даже если бы внутреннее объединение быстрее, Вы не использовали бы его при необходимости в результатах левого соединения (который включает даже записи, которые не соответствуют второй таблице в соединении).

47
задан SteveC 20 December 2012 в 05:30
поделиться

3 ответа

Я полагаю , что проблема в том, что WebRequest измеряет время только после того, как запрос действительно сделан. Если вы отправляете несколько запросов на один и тот же адрес, тогда ServicePointManager будет ограничивать ваши запросы и фактически отправлять столько одновременных подключений, сколько значение соответствующего ServicePoint.ConnectionLimit , которое по умолчанию получает значение из ServicePointManager.DefaultConnectionLimit . Хост CLR приложения устанавливает это значение 2, хост ASP - 10. Таким образом, если у вас есть многопоточное приложение, которое отправляет несколько запросов на один и тот же хост, только два фактически помещаются в сеть, остальные помещаются в очередь.

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

Еще один фактор, который следует учитывать, - это время поиска DNS. Опять же, моя вера не подкреплена вескими доказательствами, но я думаю, что WebRequest не подсчитывает время поиска DNS по таймауту запроса. Время поиска DNS может отображаться как очень большой фактор времени в некоторых развертываниях.

И да, вы должны кодировать свое приложение вокруг WebRequest.BeginGetRequestStream (для POST с контентом) и WebRequest.BeginGetResponse (для GET s и POSTS s). Синхронные вызовы не масштабируются (я не буду вдаваться в подробности почему, но у меня есть веские доказательства). Тем не мение, проблема ServicePoint ортогональна этому: поведение очереди происходит и с асинхронными вызовами.

57
ответ дан 7 November 2019 в 12:59
поделиться

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

Мне кажется:

.Timeout = время, потраченное на попытки установить соединение (не включая время поиска) .ReadWriteTimeout = время, потраченное на попытки чтения или записи данных после установления соединения

Дополнительная информация: Свойство HttpWebRequest.ReadWriteTimeout

Изменить:

Комментарий Per @ KyleM, Свойство Timeout предназначено для всей попытки подключения, и чтение его в MSDN показывает:

Timeout - это количество миллисекунд, в течение которого последующий синхронный запрос, сделанный с помощью метода GetResponse, ожидает ответа, а метод GetRequestStream ожидает для потока. Тайм-аут применяется ко всему запросу и ответу, а не по отдельности к вызовам методов GetRequestStream и GetResponse. Если ресурс не возвращается в течение периода ожидания, запрос генерирует WebException со свойством Status, установленным в WebExceptionStatus.Timeout.

(Акцент мой.)

18
ответ дан 7 November 2019 в 12:59
поделиться

Из документации свойства httpwebrequest.timeout:

Запрос системы доменных имен (DNS) может занять до 15 секунд, чтобы вернуться или время. Если ваш запрос содержит Имя хоста, которое требует разрешения и Вы устанавливаете Timeout на значение меньше, чем 15 секунд, это может занять 15 секунд или Более перед броском WebException Чтобы указать тайм-аут по вашему запросу.

Возможно ли, что ваш запрос DNS является причиной тайм-аута?

14
ответ дан 7 November 2019 в 12:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: