在某些条件下等待所有任务

时间:2014-08-07 21:45:36

标签: c# multithreading asynchronous task

我正在编写一些复杂的任务,但我无法成功解决问题。

  1. 我打开一些异步搜索某些数据的任务。
  2. 最后我等待所有任务。
  3. 我想运行所有数据,并且在完成任务之前不会停止任务。 但是,当其中一个任务找到一些相关数据时,我想继续使用等待所有任务之后的代码,但同时,我想继续搜索我的任务(直到所有数据都被读取)
  4. Here我找到了一种方法,如果其中一个任务找到数据,等待全部后如何继续代码,问题是它还会阻止所有任务运行。

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

    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方法并继续读取包含任务的数据?

    感谢。

1 个答案:

答案 0 :(得分:1)

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

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