Использование ThreadPool для каждой отдельной задачи - определенно плохая идея. Исходя из моего опыта, это больше влияет на производительность, чем помогает. Первая причина заключается в том, что для выделения потока для выполнения ThreadPool требуется значительное количество служебных данных. По умолчанию каждому приложению назначается собственный ThreadPool, который инициализируется с пропускной способностью ~ 100 потоков. Когда вы выполняете 400 операций параллельно, заполнение очереди запросами не занимает много времени, и теперь у вас есть ~ 100 потоков, все конкурирующих за циклы ЦП. Да. Платформа .NET отлично справляется с регулированием и приоритезацией очереди, однако я обнаружил, что лучше всего использовать ThreadPool для длительных операций, которые, вероятно, не будут выполняться очень часто (загрузка файла конфигурации или случайные веб-запросы). ). Использование ThreadPool для случайного запуска нескольких операций намного эффективнее, чем использование его для одновременного выполнения сотен запросов. Учитывая текущую информацию, лучший курс действий будет примерно таким:
Создайте System.Threading.Thread (или используйте одну ветку ThreadPool) с очередью, в которую приложение может отправлять запросы на
Используйте методы FileStream BeginRead и BeginWrite для выполнения операций ввода-вывода. Это приведет к тому, что .NET Framework будет использовать нативные API для потоков и выполнения IO (IOCP).
Это даст вам два рычага, один из которых заключается в том, что ваши запросы будут обрабатываться параллельно, позволяя операционной системе управлять доступом к файловой системе и многопоточностью. Во-вторых, поскольку узким местом в подавляющем большинстве систем являются жесткие диски, вы можете реализовать собственную сортировку приоритетов и регулировать поток запросов, чтобы обеспечить больший контроль над использованием ресурсов.
В настоящее время я пишу подобное приложение, и использование этого метода является одновременно эффективным и быстрым ... Без каких-либо потоков или удушения мое приложение использовало только 10-15% ЦП, что может быть приемлемо для некоторых операций в зависимости от обработки однако из-за этого мой компьютер работал медленнее, как если бы приложение использовало 80% ЦП. Это был доступ к файловой системе. Функции ThreadPool и IOCP не заботятся о том, что они перегружают компьютер, так что не запутайтесь, они оптимизированы для производительности, даже если эта производительность означает, что ваш жесткий диск сжимается, как свинья.
Единственная проблема, с которой я столкнулся, - это использование памяти, немного превышающее (50+ мегабайт) во время фазы тестирования с одновременным открытием примерно 35 потоков. В настоящее время я работаю над решением, аналогичным рекомендации MSDN для SocketAsyncEventArgs , использующим пул для одновременного выполнения x количества запросов, что в конечном итоге привело меня к этому сообщению на форуме.
Надеюсь, это поможет кому-нибудь принять решение в будущем:)