2011-06-21 67 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(