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