2013-08-27 86 views
3

我想在循環內部實現一個嵌套的任務 - 這是我迄今爲止的模式,但我很不確定,因爲這是我第一次使用並行任務庫。嵌套任務循環內

父級(層)任務應等待子節點(節點)任務完成。

public int NestedTask(IEnumerable<MatchTier> tierNodes) 
    { 
     var tier = Task<int>.Factory.StartNew(() => 
     { 
      Task<int> node = null; 

      foreach(var n in tierNodes) 
      { 
       node = Task<int>.Factory.StartNew(() => 
       { 
        // Task logic goes here 

        return 1; // temp placeholder 
       }); 

       // if a valid value is returned then exit this loop 
      } 

      return node.Result; 

     }); 

     return tier.Result; 
    } 

子節點循環,直到返回第一個有效的值,則循環將被退出,傳遞有效值父。

子節點和父節點都需要超時。每個孩子將被允許運行約3秒鐘,之後該過程將被超時並且下一個節點被詢問。

父母的總體超時值約爲15-20秒,在此之後,如果沒有收到有效的回覆,它也應該終止。

這是否合乎邏輯?

+0

老實說,你只是在等待最後的結果並返回。你真的想做什麼? – flindeberg

+0

請問您可以添加更多的細節。 tierNodes是您父節點還是子節點的共享?你如何從父節點獲取子節點。我無法在代碼中看到任何父母子女關係。多一點信息會有幫助 – Anand

+0

@Anand - 增加更多細節。 – dotnetnoob

回答

1

如上所述task.Wait(),task.Result(等待和抓取結果)和Task.WaitAll(theTaskCollection)是如何做到這一點。我已經稍微改變了你的實現來解釋這一點,但我很不確定你真的想要返回什麼。我除去了外部任務,因爲它似乎並不需要。

public int NestedTask(IEnumerable<MatchTier> tierNodes) 
{ 
    var tasks = tierNodes.Select(node => Task<int>.Factory.StartNew(() => 
      { 
       // Task logic goes here 
       return 1; // temp placeholder 
      })).ToList(); // Enumerate to start tasks, not doing this would case WaitAll to start them one at a time (i believe) 

    if (!Task.WaitAll(tasks, timeOutInMilliseconds)) 
    // Handle timeout... 

    return tasks.First().Result; // Is this what you want? 
} 

編輯:添加修改後的解決方案。

public int NestedTask(IEnumerable<string> tierNodes) 
{ 
    int parentTimeout = 15 * 1000; 
    int childTimeout = 3 * 1000; 

    var tier = Task<int>.Factory.StartNew(() => 
    { 
     foreach (var n in tierNodes) 
     { 
      var node = Task<int>.Factory.StartNew(() => 
      { 
       // Task logic goes here 
       return 1; 
      }); 

      // If we get the result we return it, else we wait 
      if (node.Wait(childTimeout)) 
       return node.Result; 
     } 
     throw new Exception("did not get result!"); 
    }); 

    if (!tier.Wait(parentTimeout)) 
    { 
     // The child will continue on running though. 
     throw new TimeoutException("parent timed out"); 
    } 
    else if (tier.Exception != null) 
    { 
     // We have an error 
     throw tier.Exception.InnerException; 
    } 

    return tier.Result; 
} 
+0

外部任務將需要,因爲下一個階段將添加一些超時邏輯。但是爲了清楚起見,我沒有這麼做。 – dotnetnoob

+0

@dotnetnoob爲什麼不在較低的任務級別有超時? – flindeberg

+0

不同的超時時間將適用於每個節點 - 節點將有3秒的超時時間,並且parernt層的超時時間爲15-20秒。超時前允許每個節點運行指定的時間。下一個節點被測試,依此類推,直到返回calid值或所有節點耗盡。如果父級超時發生,整個過程將被放棄,並且下一級將被測試。 – dotnetnoob

3

等待任務完成不

node.Wait(); 

等待任務,直到一些蜱做

node.Wait(timeToWait); 

或等待他們全部完成

Task.WaitAll(tasks); 

並且您應該閱讀here以獲取更多信息

+0

我明白,使用parent.Result會強制父母等待。 – dotnetnoob

+0

@dotnetnoob你正在做node.Result只在最後一項... –