2013-10-12 36 views
0

我该如何获得ContinueWith等待两个任务完成而不是一个?任务继续带事件链序列

我想确定如何将一组Task链接在一起,并让一个接一个接着几个链接级别。我有三个级别的链接。在第一级,我有一项任务。我想在第二级开始之前完成最高级别。在第二级,我有3个任务。我想在三级任务开始前完成三项任务中的两项。


TopLevel > SecondLevel A \ ThirdLevel 
      SecondLevel B/
      SecondLevel C - Don't wait for this one for the third level 

我写了下面的示例程序来测试如何做到这一点的工作方式如下

class Program 
{ 
    private static Random rand = new Random(); 
    public static Random Rand { get { return rand; } } 
    static void Main(string[] args) 
    { 

     Task topLevelTask = new Task(() => DoSomeWork("topLevelTask")); 
     Task secondLevelTaskA = topLevelTask.ContinueWith((task) => DoSomeWork("secondLevelTaskA"), TaskContinuationOptions.AttachedToParent); 
     Task secondLevelTaskB = topLevelTask.ContinueWith((task) => DoSomeWork("secondLevelTaskB"), TaskContinuationOptions.AttachedToParent); 
     Task secondLevelTaskC = topLevelTask.ContinueWith((task) => DoSomeWork("secondLevelTaskC"), TaskContinuationOptions.AttachedToParent); 
     Task thirdLevelTask = secondLevelTaskA.ContinueWith((task) => DoSomeWork("thirdLevelTask"), TaskContinuationOptions.AttachedToParent); 

     topLevelTask.Start(); 
     Console.ReadLine(); 
    } 

    private static void DoSomeWork(string task) 
    { 
     int sleep = Rand.Next(10000); 
     Console.WriteLine("Thread {0}: Ticks {1}: Task {2}: Sleep: {3}", Thread.CurrentThread.ManagedThreadId, DateTime.Now, task, sleep); 
     Thread.Sleep(sleep); 
     Console.WriteLine("Complete Task {0}", task); 
    } 
} 

对于这个不正是我想要的大部分。它启动第一个任务并等待它完成,并行启动3个二级任务。但是,我无法弄清楚如何设置第三级来等待taskA和taskB,因为ContinueWith设置了单个父任务。

我曾尝试将ContinueWith用于taskA和taskB上的第三级任务,但之后它运行了两次。任何帮助,将不胜感激。这是我的示例程序的输出。

Program Output

+0

http://stackoverflow.com/help/privileges/vote-down – Harrison

回答

4

您正在寻找ContinueWhenAll()

Task thirdLevelTask = Task.Factory.ContinueWhenAll(
    new[] { secondLevelTaskA, secondLevelTaskB }, 
    tasks => DoSomeWork("thirdLevelTask"), 
    TaskContinuationOptions.AttachedToParent); 

这样做的优势是Task.WhenAll().ContinueWith(),它会在.NET 4.0工作了。如果你使用.Net 4.5,使用async - await而不是ContinueWith()可能会更好。

0

我想通了。如果我更换

Task thirdLevelTask = secondLevelTaskA.ContinueWith((task) => DoSomeWork("thirdLevelTask"), TaskContinuationOptions.AttachedToParent); 

Task thirdLevelTask = Task.WhenAll(secondLevelTaskA,secondLevelTaskB).ContinueWith((task) => DoSomeWork("thirdLevelTask"), TaskContinuationOptions.AttachedToParent); 

它会做我想做的。这是新的输出。

enter image description here