2013-10-01 3 views
0

Согласно известному графику, мне нужно вызвать метод Run для заданного списка задач.Каковы исключительные случаи использования пула потоков

В настоящее время я использую синхронный вызов только из основного потока.

foreach (var task in tasksToRunInCurrentBatch) 
{ 
    Run(task.Key, task.Value); 
} 

Этот код будет, вероятно, должны быть улучшены, так как tasksToRunInCurrentBatch может иметь более 10k задач, и я хочу, чтобы минимизировать общее время, пока последняя задача не была выполнена.

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

Я рассматриваю возможность использования пула потоков в качестве решения.

так я начал, читая несколько статей - How to: Use a Thread Pool, Using Threading

Эти статьи объясняют основы, где все выглядит слишком хорошо. Каковы исключительные случаи использования пула потоков в текущем контексте?

+0

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

+0

@ HansPassant - Почему они «сталкиваются»? –

+0

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

ответ

1

Посмотрите на this extensive article on threading. В разделе Concurrent collections вы можете найти пример очереди producer/consumer, выполняющей задачи.

В общем соображении не следует создавать объекты 10k Task и Run() их всех. Вместо этого создайте nTask экземпляры, которые будут выполнять методы 10k, которые вы хотите выполнить.

EDIT

Если вы хотите использовать ThreadPool выполнить методы, которые вы должны принять во внимание следующее:

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

С другой стороны Task Parallel Library, который построен на вершине ThreadPool предлагает элегантные способы решения вышеуказанных проблем. Пример PCQueue из приведенной выше ссылки (Concurrent collections) показывает вам, как бороться с исключениями, которые вы выбрали из вызываемого вами Action, и предоставляет способ продолжить поток приложений, когда все действия завершены.

Вы можете использовать PCQueue так:

var queue = new PCQueue(Environment.ProcessorCount); 
var tasks = tasksToRunInCurrentBatch.Select(t=>queue.Enqueue(t.Value)).ToArray(); 
Task.WaitAll(tasks); 
+0

Я не вижу в вашем ответе слов - пул потоков. –

+0

@Yossi, это потому, что вы, вероятно, не должны его использовать. 'Задача' 'TreadPool' внутренне, но обеспечит вам большую гибкость и уменьшит накладные расходы на разработку. – RePierre

+0

Даже если этого примера недостаточно, попробуйте ответить на вопрос. –

Смежные вопросы