2011-06-21 35 views
2

我遇到了麻烦。我有“WorkItem”,它有一个方法DoWork。 WorkItem可以具有必须完成的依赖关系,否则会抛出异常。任务并行库 - 构建树

下面是一个图表,其中每个项目(A,B,C等)都是一个WorkItem。因此,排名第一的项目应该是A,B,E,因为他们没有依赖关系。

Diagram

所以我把 “G” 到DoWorkForTask,但我的异常抛出本身,这证明,也就是说,A和B不是C运行之前完成。整个微小项目zipped up here.

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); 
    } 

请注意,我读过this thread,并没有解决问题。

回答

2

我不确定为什么要将“工作流程”的结构封装到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")); 
3

这看起来可疑的对我说:

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

你忽略了child - 你只是调用DoWork多次,你有孩子。

你的意思是:

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

+0

对不起,我加回原来的DoWorkForTask()。 –

+0

@George:好的,很难掌握你在这里所有的小部分,你能告诉我们一个简短的*完整*程序,它演示了这个问题? –

+0

我已经重新整理了整篇文章,希望更清楚! –

-1

您可能需要提供一个机制,为子任务完成如Task.WaitAll(