2010-07-28 2 views
0

Я работаю с новой библиотекой TPL .NET и сталкиваюсь с каким-то странным поведением для меня, я не могу объяснить. По какой-то причине вложенная задача не запускается в моем случае. Я упростил решение, которое я к следующему:Задача параллельной библиотеки. Вложенная задача не запускается

 bool flag = false; 

     for (int i = 0; i < 5; i++) 
     { 
      Task.Factory.StartNew(() => 
         { 
          while (true) // a lot of newcoming tasks 
          { 
           Thread.Sleep(200); //do some work 
           Task.Factory.StartNew(() => 
              { 
               flag = true; 
               }); 
          } 
         }); 
     } 

     Thread.Sleep(2000); 
     Assert.IsTrue(flag); 

У меня есть 5 задач, которые, работающих одновременно. Каждая задача извлекает некоторые элементы из ожидающей очереди, выполняет некоторую операцию и затем пытается запустить вложенную задачу для результатов этой операции. Проблема в том, что если слишком много элементов (в то время как (true) имитирует это), и все 5 задач постоянно выполняются, вложенные задачи не запускаются. Пуск может быть запущен только после выполнения большинства задач с завершением цикла while.

кажется что-то с в то время как заявления, которое блокирует вложенные задачи для запуска, но я не знаю, что :)

ответ

3

Task.Factory.StartNew не запускает задачу, она добавляет задачу в список запланированных задач, и планировщик получает решение, когда запускать задачу на основе таких вещей; количество доступных ядер (размер пула потоков), текущая загрузка ЦП и пропускная способность существующей работы.

Вы должны прочитать раздел о планировании задач здесь:

http://parallelpatterns.codeplex.com/releases/view/48562

Page 63 PDF года.

Опция LongRunning «исправляет» вашу проблему, полностью обходя пул потоков. Это имеет некоторые недостатки в том, что он позволит вам создавать больше потоков, чем ваша система должна действительно использовать, это ухудшит производительность, вызвав чрезмерное переключение контекста.

Эксперименты, такие как код, который у вас был выше, с использованием потока сна, вводят в заблуждение, потому что они «обманывают» планировщика. Он видит, что он добавил больше работы, и все же загрузка процессора не увеличилась.63 Вы должны заменить сон плотным контуром, который содержит математику (например, например, вычисление Sqrt().

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

следующий ответ может быть стоит посмотреть:

Parallel Task Library WaitAny Design

0

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

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

+0

Да. Они начинаются позже, но я хочу, чтобы они начинались параллельно с выполнением задач. Если я изменю ограничение для индекса «i» в цикле, например, 10, у меня будет создано и работает 10 потоков. Но ни одна вложенная задача не будет выполняться параллельно этим задачам. – lostaman

+0

Добавление TaskCreationOptions.LongRunning для родительских задач решило проблему. – lostaman

+0

Решает проблему в приведенном ниже примере, но не в моем проекте :( – lostaman

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