Хороший способ всегда запускать 10 задач TPL и запускать новую после завершения цикла? - PullRequest
2 голосов
/ 04 декабря 2011

У меня есть приложение Winform, и я изучаю TPL для параллельного программирования.WinForm работает непрерывно и ведет 10 веб-сайтов одновременно.Каждый веб-сайт обрабатывается задачей TPL.Задачи не зависят друг от друга.Каждый раз, когда задача выполнена, запускается новая задача.Я намерен использовать Task.Factory.StartNew (..) для запуска задач.

Я знаком с запуском задач TPL, но не понимаю, как запускать несколько задач TPL одновременно в цикле и запускатьновый каждый раз, когда каждый завершает, эффективно имея 10 задач всегда.

Как я могу это сделать?

Ответы [ 3 ]

2 голосов
/ 04 декабря 2011

Если у вас есть список, скажем, 1000 URL, но вы хотите обрабатывать не более 10 одновременно, самый простой способ сделать это - использовать Parallel::ForEach с ParallelOptions с MaxDegreeOfParallelism из 10, например:

Parallel.ForEach(myListOfUrls,
    new ParallelOptions
    {
        MaxDegreeOfParallelism = 10
    },
    url =>
    {
        // processing here
    });
0 голосов
/ 26 марта 2012

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

public static void ParallelWhileNotEmpty<T>(
  IEnumerable<T> initialValues, 
  Action<T, Action<T>> body)
{
  var opts = new ParallelOptions { MaxDegreeOfParallelism = 10 };
  var from = new ConcurrentQueue<T>(initialValues);  
  while (!from.IsEmpty)
  { 
    var to = new ConcurrentQueue<T>();
    Action<T> addMethod = to.Enqueue; 
    Parallel.ForEach(from, opts. body(v, addMethod));        
    from = to;
  }
}

Таким образом, «петля» разомкнута и будет продолжаться до тех пор, пока вы не закончите работу. Очевидно, что ваше реальное приложение будет учитывать дублирующиеся URL-адреса, а не добавлять их и т. Д. Но это позволяет вашему приложению динамически добавлять работу. Вы можете использовать ParallelOptions для ограничения параллелизма или написать планировщик.

Подробнее о параллелизме динамических задач см.

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

Полный код для примера см.

http://parallelpatterns.codeplex.com/SourceControl/changeset/view/54510#795590

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

Если вы хотите, чтобы пользовательский планировщик ограничивал степень параллелизма, см. Пример на MSDN

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

0 голосов
/ 04 декабря 2011

Используйте свой собственный планировщик для TaskFactory.

http://www.codeguru.com/csharp/article.php/c18931/

Затем назначьте 10 потоков через этот планировщик.

...