在一定条件下等待所有任务



我正在写一些复杂的任务,我不能成功地解决问题。

  1. 我打开一些任务来异步搜索一些数据。
  2. 最后等待所有的任务。
  3. 我想运行所有的数据,不停止任务,直到他们全部完成。但是,当其中一个任务找到一些相关数据时,我想继续执行等待所有任务后的代码,但同时,我想继续使用我的任务进行搜索(直到所有数据都被读取)。

在这里,我找到了一种方法,如何在等待所有任务后继续代码,如果其中一个任务找到了数据,问题是它也停止了所有任务的运行。

这是我的代码(这只是演示问题的代码)。

private static void RunTasks()
{
    TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
    Task<bool> t0 = Task.Factory.StartNew<bool>(() => Find(1, 2));
    Task<bool> t1 = Task.Factory.StartNew<bool>(() => Find(4, 7));
    Task<bool> t2 = Task.Factory.StartNew<bool>(() => Find(13, 14));
    t0.ContinueWith(_ =>
    {
        if (t0.Result)
            tcs.TrySetResult(t0.Result);
    });
    t1.ContinueWith(_ =>
    {
        if (t1.Result)
            tcs.TrySetResult(t1.Result);
    });
    t2.ContinueWith(_ =>
    {
        if (t2.Result)
            tcs.TrySetResult(t2.Result);
    });
    tcs.Task.Wait();
    Console.WriteLine("Found");
    ContinueWork(); //Runs after at least one data found or when all tasks finish.
}
//Just for demonstration...
private static bool Find(int a, int b)
{
    Console.WriteLine("a: " + a + " b: " + b);
    return a == 4 && b == 7 ? true : false;
}

我该如何写它,以便当发现一些数据时,它将继续使用ContinueWork方法,并且还将继续使用任务读取数据?

谢谢。

这不是最干净的方式,但它将满足您的目的:

            TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
            Task<bool>[] tasks = new Task<bool>[3];
            tasks[0] = Task.Factory.StartNew<bool>(() => Find(1, 2));
            tasks[1] = Task.Factory.StartNew<bool>(() => Find(4, 7));
            tasks[2] = Task.Factory.StartNew<bool>(() => Find(13, 14));
            tasks[0].ContinueWith(_ =>
            {
                if (tasks[0].Result)
                    tcs.TrySetResult(tasks[0].Result);
            });
            tasks[1].ContinueWith(_ =>
            {
                if (tasks[1].Result)
                    tcs.TrySetResult(tasks[1].Result);
            });
            tasks[2].ContinueWith(_ =>
            {
                if (tasks[2].Result)
                    tcs.TrySetResult(tasks[2].Result);
            });
            Task.WaitAny(tasks);
            Console.WriteLine("Found");
            ContinueWork();

最新更新