Я разрабатываю приложение (winforms С#.NET 4.0), где я обращаюсь к функциональности поиска от стороннего пользователя с помощью простого HTTP-запроса. Я вызываю url с параметром, и взамен я получаю небольшую строку с результатом поиска. Достаточно просто.
Однако проблема заключается в том, что мне приходится делать много этих поисков (пару тысяч), и я хотел бы ограничить необходимое время. Поэтому я хотел бы запускать запросы параллельно (скажем, 10-20). Я использую ThreadPool для этого, а короткая версия моего кода выглядит так:
public void startAsyncLookup(Action<LookupResult> returnLookupResult)
{
this.returnLookupResult = returnLookupResult;
foreach (string number in numbersToLookup)
{
ThreadPool.QueueUserWorkItem(lookupNumber, number);
}
}
public void lookupNumber(Object threadContext)
{
string numberToLookup = (string)threadContext;
string url = @"http://some.url.com/?number=" + numberToLookup;
WebClient webClient = new WebClient();
Stream responseData = webClient.OpenRead(url);
LookupResult lookupResult = parseLookupResult(responseData);
returnLookupResult(lookupResult);
}
Я заполняю numbersToLookup
(a List<String>
) из другого места, вызываю startAsyncLookup
и предоставляю ему функцию обратного вызова returnLookupResult
для возврата каждого результата. Это работает, но я обнаружил, что я не получаю пропускную способность, которую хочу.
Первоначально я думал, что это может быть третья сторона, у которой плохая система на конце, но я исключил это, поставив одновременно один и тот же код на двух разных машинах. Каждый из них занимал столько же, сколько сделал один, поэтому я мог исключить это.
Затем коллега сказал мне, что это может быть ограничением в Windows. Я немного искал googled и нашел среди других этот пост, говорящий, что по умолчанию Windows ограничивает количество одновременных запросов на один и тот же веб-сервер до 4 для HTTP 1.0 и до 2 для HTTP 1.1 (для HTTP 1.1 это фактически соответствует спецификации (RFC2068)).
То же самое сообщение, о котором говорилось выше, также предоставило возможность увеличить эти ограничения. Добавив два значения реестра в [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings]
(MaxConnectionsPerServer и MaxConnectionsPer1_0Server), я мог бы сам это контролировать.
Итак, я попробовал это (сидел до 20), перезапустил свой компьютер и снова попытался запустить свою программу. К сожалению, это ничуть не помогло. Я также следил за Монитором ресурсов (см. Снимок экрана) во время запуска пакетного поиска, и я заметил, что мое приложение (одно с заголовок затемнен) все еще использовал только два TCP-соединения.
Итак, вопрос в том, почему это не работает? Является ли сообщение, связанное с неправильными значениями реестра? Возможно, это невозможно "взломать" в Windows больше (я на Windows 7)?
Любые идеи будут высоко оценены:)
И на всякий случай, когда кто-то должен удивляться, я также пробовал с различными настройками MaxThreads на ThreadPool (от 10 до 100), и это, похоже, не повлияло на мою пропускную способность, поэтому проблема не должна быть там тоже.