Оптимальное количество элементов для хранения в очереди пула потоков в .NET?

StackOverflow https://stackoverflow.com/questions/1840073

  •  12-09-2019
  •  | 
  •  

Вопрос

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

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

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

Итак, вопрос в том, как мне вычислить это число N, количество элементов, которые нужно поместить и сохранить в очереди пула потоков.

Проблемы, которые я рассмотрел:

  • Возможно, я захочу поставить в очередь 2 * количество процессоров, которое, как я вижу, является типичным количеством элементов, чтобы гарантировать, что все процессоры работают.
  • Однако если фактическая обработка некоторых элементов происходит очень быстро (что может случиться), то очередь в пуле потоков исчерпается до того, как мой собственный класс сможет заполниться дополнительной работой, поэтому, возможно, мне хотелось бы большее число, чтобы избежать недостаточного использования ресурсов. процессоры
  • Должен ли я создать какую-то процедуру автоматической настройки для расчета оптимального числа на основе текущего времени, которое занимает каждый элемент, чтобы, если все они сверхбыстрые, число было намного выше, а если обработка занимает немного времени, оно должно оставаться низкий?

Что вы думаете?

Новый:Хорошо, в связи с одним из ответов, я объясню немного больше.Каждый элемент, помещенный в очередь, имеет уникальный ключ.Если я добавлю в очередь другой элемент с тем же ключом, что и существующий элемент, этот старый элемент считается «Отброшенным» и должен быть удален.Если элемент обрабатывается, для свойства элемента рабочей нагрузки устанавливается значение true, свойство IsDicarded, за вызов которого отвечает метод обработки.Если он обнаружит выброшенный предмет, он должен завершить работу раньше, не возвращая никаких результатов.

Возможно, мне следует еще немного поэкспериментировать и попытаться просто сбросить все в пул потоков.

Новый вопрос:Есть ли ограничение на количество предметов, которые я могу поставить в очередь?Если нет, то это значительно упростило бы мой класс.

Примечание:Когда я говорю «длительная обработка», я имею в виду порядка 1–10 секунд.Является ли пул потоков лучшим для этого?Я вижу в Интернете заметки о том, что «обработка должна быть быстрой», но что такое «быстрая» никогда не упоминается.Здесь быстрота порядка миллисекунд?

Это было полезно?

Решение

Знаешь ли ты бар Ами? Умный пул потоков?

Кажется, его реализация позволяет отменить необработанный элемент и динамически увеличивать количество потоков по мере необходимости до достижения жесткого предела;Я лично использую 100 * Environment.ProcessorsCount

Другие советы

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

Количество операций, которые могут быть в очереди в пуле потоков, ограничено только доступной памятью;Однако пул потоков ограничивает количество потоков, которые могут быть активны в процессе одновременно.По умолчанию предел составляет 250 рабочих потоков на процессор и 1000 потоков завершения ввода/вывода.

Вы можете управлять максимальным количеством потоков, используя методы GetMaxThreads и SetMaxThreads.

http://msdn.microsoft.com/en-us/library/0ka9477y.aspx

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top