Должны ли мы использовать собственные потоки или пул потоков для небольших и частых задач? - PullRequest
1 голос
/ 09 марта 2012

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

Я могу реализовать это двумя способами:

  1. Создать отдельный поток для каждого плагина, который будет обрабатывать события из очереди плагина, пока очередь не станет пустой. Затем спать, пока новое событие не придет в очередь, обработать его и т. Д.

  2. Когда события поступают в очередь плагина, обрабатывают его в потоке пула потоков. Когда очередь опустеет, верните ее в пул потоков.

Вопрос: Каковы преимущества и недостатки обоих способов?

Некоторые уточнения:

  • Плагины не слишком загружают процессор, большую часть времени они просто ждут следующего события.
  • Меня не волнует время, необходимое для создания потока, плагины долговечны.
  • Обычно у меня есть ~ 10-20 таких плагинов на приложение.

Ответы [ 3 ]

2 голосов
/ 09 марта 2012

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

Если это ваше требование, я бы подумал о сборкеплагины вокруг BlockingCollection<T>.Когда вы добавляете плагин, запускайте долгосрочную задачу, которая просто выполняет foreach на BlockingCollection.GetConsumingEnumerable().

. Это позволит вам добавлять элементы в их «очередь», и плагин будет автоматически обрабатывать эти элементыв порядке, не требуя собственной обработки «сна».Каждый плагин может просто использовать blockingCollection.GetConsumingEnumerable для обработки элементов в своей очереди.

1 голос
/ 11 марта 2012

Я бы пошел с # 2.Причина в том, что вы не держите кучу потоков, которые простаивают большую часть времени.На самом деле нет недостатка в том, чтобы делать это таким образом, поскольку вы также получаете параллелизм между различными плагинами и последовательное выполнение для каждого данного плагина.

1 голос
/ 09 марта 2012

Я видел, как это делалось в обе стороны. То, что становится уродливым с одним потоком на каждый плагин, так это то, что вы начинаете полагаться на идею, что «только один поток когда-либо касается моего плагина», а затем кто-то делает ошибку, когда поток одного плагина идет и касается другого плагина (хотя замысловатая обработка событий) или что-то подобное). Тогда вы получите очень трудные для отслеживания условия гонки.

Подход, предложенный @ Reed-Copsey, гораздо чище, но если вам нужно использовать один из двух упомянутых вами подходов, то использование пула потоков и соответствующая блокировка в будущем избавят вас от душевных страданий. Это особенно применимо, если у вас есть несколько членов команды, работающих над несколькими аспектами проекта.

...