Задача Parallel Library - построение дерева - PullRequest
2 голосов
/ 21 июня 2011

У меня проблемы с этим. У меня есть «WorkItem», который имеет метод DoWork. WorkItem может иметь зависимости, которые ДОЛЖНЫ завершаться раньше, чем это происходит, в противном случае он вызывает исключение.

Вот диаграмма, где каждый элемент (A, B, C и т. Д.) Является WorkItem. Таким образом, первыми элементами, не относящимися к званию, должны быть A, B, E, поскольку они не имеют зависимостей.

Diagram

Поэтому я выбрасываю «G» в DoWorkForTask, но мое исключение выдает себя, доказывая, что, скажем, A и B не завершили до запуска C Весь крошечный проект запакован здесь.

    private void DoWorkForTask(WorkItem item)
    {
        // NOTE: item relies on Dependents to complete before it proceeds
        Task.Factory.StartNew(() => 
        {
            foreach (var child in item.Dependents)
            {
                Task.Factory.StartNew(child.DoWork, TaskCreationOptions.AttachedToParent);

                if (child.Dependents.Count > 0)
                    DoWorkForTask(child);
            }

            item.DoWork();
        }, TaskCreationOptions.AttachedToParent);
    }

Обратите внимание, что я прочитал эту ветку , и это не решает проблему.

Ответы [ 3 ]

3 голосов
/ 21 июня 2011

Мне это кажется подозрительным:

Parallel.ForEach(item.Dependents, child => DoWork());

Вы игнорируете child - вы просто звоните DoWork столько раз, сколько у вас детей.

Вы имели в виду:

Parallel.ForEach(item.Dependents, child => child.DoWork());

2 голосов
/ 09 июля 2011

Я не уверен, почему вы хотите инкапсулировать структуру «рабочего процесса» в класс WorkItem.Но если вам это не нужно, то будет работать что-то подобное:

var A = Task.Factory.StartNew(
  () => Console.WriteLine("A"));
var B = Task.Factory.StartNew(
  () => Console.WriteLine("B"));
var E = Task.Factory.StartNew(
  () => Console.WriteLine("E"));
var C = Task.Factory.StartNew(
  () => { Task.WaitAll(A, B); Console.WriteLine("C"); });
var D = Task.Factory.StartNew(
  () => { Task.WaitAll(C, E); Console.WriteLine("D"); });
Task.Factory.StartNew(
  () => { Task.WaitAll(E, D); Console.WriteLine("F"); })
    .ContinueWith(a => Console.WriteLine("G"));
0 голосов
/ 23 ноября 2015

Может потребоваться предоставить механизм для выполнения дочерних задач, например, Task.WaitAll (

...