Я занимаюсь разработкой приложения (winforms C # .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
(List<String>
) из другого места, звоню startAsyncLookup
и предоставляю ему функцию обратного вызова returnLookupResult
для возврата каждого результата. Это работает, но я обнаружил, что не получаю желаемую пропускную способность.
Первоначально я думал, что это может быть третья сторона, имеющая плохую систему на своем конце, но я исключил это, пытаясь запустить один и тот же код с двух разных машин одновременно. Каждый из них занимал столько же времени, сколько и один, поэтому я мог исключить это.
Затем коллега сообщил мне, что это может быть ограничением в Windows. Я немного погуглил и обнаружил среди прочего этот пост о том, что по умолчанию 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), и это никак не сказалось на моей пропускной способности, поэтому проблема не должна быть там тоже.