Задача параллельной библиотеки. Вложенное задание не запускается - PullRequest
0 голосов
/ 28 июля 2010

Я работаю с новой библиотекой 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 завершат свое выполнение.

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

Ответы [ 2 ]

3 голосов
/ 31 июля 2010

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

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

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

Страница 63 из PDF.

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

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

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

Может быть стоит взглянуть на следующий ответ:

Библиотека параллельных задач WaitAny Design

0 голосов
/ 28 июля 2010

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

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

...