0

如何让我ContinueWith等待两个任务完成而不是一个?

我想确定如何将一组Tasks 链接在一起,并让一个在另一个之后运行具有多个链接级别。我有三个级别的链接。在第一关,我只有一个任务。我希望在第二级开始之前完成顶级。在第二级,我有 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 上放置第三级任务,但随后它运行了两次。任何帮助,将不胜感激。这是我的示例程序的输出。

程序输出

4

2 回答 2

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().

于 2013-10-12T18:18:25.993 回答
0

我想到了。如果我更换

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

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

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

在此处输入图像描述

于 2013-10-12T17:23:08.440 回答