TPL等待任务的完成与一个特定的返回值返回值、任务、TPL

2023-09-03 04:50:49 作者:像我这样

我想提出一个要求于X不同的网络服务谁将会各自返回要么

I'd like to make a request to X different web services who will each return either true or false.

这些任务应该并行执行,我想等待第一个完成的与一个真正的价值。当我收到一个真正的价值,我不希望等待其他任务完成。

These tasks should be executed in parallel and I'd like to wait for the first one that completes with a true value. When I receive a true value, I do not wish to wait for the other tasks to complete.

在下面的例子中, T1 不应该的期待已久的的,因为 T3 首先完成并返回

In the example below, t1 should not be awaited since t3 completes first and returns true:

var t1 = Task.Run<bool>(() =>
{
    Thread.Sleep(5000);
    Console.WriteLine("Task 1 Excecuted");
    return true;
}, cts.Token);

var t2 = Task.Run<bool>(() =>
{
    Console.WriteLine("Task 2 Executed");
    return false;
}, cts.Token);

var t3 = Task.Run<bool>(() =>
{
    Thread.Sleep(2000);
    Console.WriteLine("Task 3 Executed");
    return true;
}, cts.Token);

基本上我正在寻找 Task.WhenAny 以predicate,这当然是不存在的。

Essentially I'm looking for Task.WhenAny with a predicate, which of course doesn't exist.

推荐答案

您可以简单地使用 Task.WhenAny 和predicate多次,直到正确的任务走来

You can simply use Task.WhenAny and a predicate multiple times until the "right" task comes along

async Task<T> WhenAny<T>(IEnumerable<Task<T>> tasks, Func<T, bool> predicate)
{
    var taskList = tasks.ToList();
    Task<T> completedTask = null;
    do
    {
        completedTask = await Task.WhenAny(taskList);
        taskList.Remove(completedTask);
    } while (!predicate(await completedTask) && taskList.Any());

    return completedTask == null ? default(T) : await completedTask;
}