【问题标题】:Wait all tasks with some conditions在某些条件下等待所有任务
【发布时间】:2014-08-08 06:39:52
【问题描述】:

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

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

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 方法,并且还会继续使用任务读取数据?

谢谢。

【问题讨论】:

  • 不确定是什么问题。你说这个代码一设置结果就停止执行任务?我无法重现该问题。它执行所有三个任务。我错过了什么吗?
  • 如果我理解正确,也许你需要用这 3 个任务创建一个任务数组,然后调用 Task.WhenAny 传递数组。
  • @SriramSakthivel 当我找到一个结果时任务停止。但我不想要它。
  • @terrybozzio 我想过WhenAny,但问题是当find返回true时WhenAny会停止所有任务。还是我错了?
  • 它将在“那个地方”等待,直到第一个结果出现,然后它从那个地方继续,任务将全部结束。

标签: c# multithreading asynchronous task


【解决方案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();

【讨论】:

    猜你喜欢
    • 2020-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多