HttpWebRequest и порты завершения ввода / вывода - PullRequest
6 голосов
/ 24 января 2011

Я работаю над приложением, которое требует, чтобы один тип сообщения попадал в базу данных, а другой тип сообщения - на внешний XML-файл.

Мне нужно обработать LOT... одна из больших проблем заключается в том, чтобы класс HttpWebRequest работал хорошо.Сначала я просто использовал стандартные синхронные методы и все эти потоки.Это было нехорошо.

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

У меня есть поток, который вращается иотправляет мне доступные рабочие потоки + порты завершения в пуле потоков.Количество портов завершения всегда очень низкое (максимум, что я видел, используется 9), и я всегда использую около 120 рабочих потоков (иногда больше).Я использую шаблон начала / конца для всех методов в httpwebrequest:

Begin/EndGetRequestStream
Begin/EndWrite (Stream)
Begin/EndGetResponse
Begin/EndRead (Stream)

Я правильно делаю?Я что-то пропустил?Я могу использовать (иногда) до 2048 http-соединений одновременно (из вывода netstat) - почему номера портов завершения должны быть такими низкими?

Если кто-нибудь может дать несколько серьезных советов о том, как преуспеть с этим управляющим работникомпотоки, порты завершения и httpwebrequest было бы очень признательно!

РЕДАКТИРОВАТЬ: .NET является разумным инструментом для этого?Могу ли я получить большое количество http-соединений, работающих с .NET и стеком System.Net?Было предложено использовать что-то вроде WinHttp (или другой библиотеки C ++) и вызывать его из .NET, но я не хочу этого делать!

Ответы [ 3 ]

6 голосов
/ 24 января 2011

Насколько я понимаю, вы не связываете порт завершения ввода / вывода все время, когда асинхронный запрос не выполнен - ​​он только "занят", когда данные возвращены и находятся в процессе обрабатывается в соответствующей теме. Надеюсь, у вас нет очень большой работы в обратном вызове, поэтому у вас не так много одновременно используемых портов.

Вы на самом деле получаете низкую производительность, хотя? Ваша причина для беспокойства только низкие числа? Вы получаете ожидаемую пропускную способность?

Одна проблема, с которой вы можете столкнуться, заключается в том, что пул HTTP-соединений для любого хоста относительно мал. Если у вас есть сотни запросов к одному и тому же компьютеру, то по умолчанию только 101 запрос будет на самом деле за один раз, чтобы избежать DoS-атаки на рассматриваемый хост (и получить преимущества keep-alive ). Вы можете увеличить это программно или используя app.config. Конечно, это не может быть проблемой в вашем случае, либо потому, что вы уже исправили проблему, либо потому что все ваши запросы относятся к разным хостам. (Если netstat показывает 2048 соединений, это звучит неплохо.)

0 голосов
/ 16 февраля 2011

Наличие только 9 потоков портов завершения фактически означает, что вы, вероятно, используете их правильно и эффективно. Я собираюсь предположить, что машина, на которой вы работаете, имеет либо 8 ядер, либо 4 гиперпоточных ядра, что означает, что ОС будет пытаться поддерживать до 8 активных (не спящих / блокирующих / ожидающих) потоков портов завершения в любое время.

Если один из запущенных потоков становится неактивным (спящий / блокирующий / ожидающий) и имеются дополнительные рабочие элементы для обработки, то будет создан дополнительный поток для сохранения активного счетчика на уровне 8. Если вы видите 9 потоков, это означает, что что вы практически не блокируете методы в потоках портов завершения и фактически выполняете с ними работу процессора.

Если у вас 8 потоков, активно выполняющих работу с привязкой к ЦП на 8 ядрах, то добавление большего количества потоков только замедлит работу (переключение контекста между потоками будет потрачено впустую).

То, на что вам следует обратить внимание, - это почему у вас 120 других потоков и что они делают.

0 голосов
/ 26 января 2011

Возможно, ваши методы EndRead должны записывать результат только в потокобезопасную очередь, которую вы затем читаете из небольшого числа рабочих потоков, находящихся под вашим контролем.И / или используйте тот факт, что HttpWebRequest сообщит об ожидаемом объекте, когда это будет сделано, и напишет собственную логику для ожидания всех ожидающих запросов от одного (или небольшого числа) потока.

...