@ATauenis

Как побороть timeout'ы на ровном месте в WebClient?

Всем доброго %времясуток%! Есть программка, регулярно качающая файлы по HTTPS. Зачастую бывает, что по 20-30 штук сразу (мелкого объёма). Периодически часть запросов подвисает, и затем отваливается по таймауту. Заметил, что чаще всего зависания+таймауты приходятся на группы запросов, начавшихся в неудачное время +/- 10 сек.. Если перезапустить программу, сеть для неё оживает. Тоже самое, если подождать пару минут, и дать всем запросам оттаймаутиться. Потом всё нормально работает какое-то время, до повторения глюка.

Какие есть варианты, почему это происходит? Из браузеров, скайпа, иного сетевого ПО проблем никаких, сеть стабильна. Серверы тоже из другого софта отзываются всегда.

Обращения сделаны двумя способами.
1-й:
WebClient WC = new WebClient(); //not HttpClient because it's appear in .net 4.0
Exception WCerr = null;

WC.OpenReadAsync(new Uri(SrcUrl)); //not OpenReadTaskAsync for compatibility with WinXP
WC.OpenReadCompleted += (object sender, OpenReadCompletedEventArgs e) =>
{
if (e.Error != null) { WCerr = e.Error; return; }
if (ConvStdin is MemoryStream) ConvStdin = e.Result;
};
while (ConvStdin is MemoryStream && WCerr == null) { /*wait*/ }
if (WCerr != null) throw WCerr.InnerException ?? WCerr; //вот тут вылезает Timeout


2-й:
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(Host);
AddHeaders(Headers, webRequest); //моя функция, тут всё нормально
webRequest.Method = Method;
webRequest.AllowAutoRedirect = AllowAutoRedirect;
webRequest.CookieContainer = CC;
webRequest.ProtocolVersion = HttpVersion.Version11;
webRequest.KeepAlive = true;
webRequest.ServicePoint.Expect100Continue = false;

webResponse = (HttpWebResponse)webRequest.GetResponse(); //иногда лезет WebException, Timeout


Оба задолбали выкаблучиванием.
  • Вопрос задан
  • 837 просмотров
Решения вопроса 1
petermzg
@petermzg
Самый лучший программист
Вы наверное знаете, что существует лимит на кол-во подключений к одному хосту. По умолчанию 2 конекта для обычных приложений и 10 для приложений запущенных как ASP.NET host.
ServicePointManager.DefaultConnectionLimit
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
AlexanderYudakov
@AlexanderYudakov
C#, 1С, Android, TypeScript
По окончании обработки HttpWebResponse нужно обязательно вызывать Dispose(), например, так:

using (var webResponse = (HttpWebResponse)webRequest.GetResponse())
{
    // обработка ответа
}


А задирать до небес ServicePoint.ConnectionLimit — это костыль.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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