Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TPL wait for task to complete with a specific return value

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.

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

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

like image 517
Ben Foster Avatar asked Jul 03 '14 10:07

Ben Foster


People also ask

How do I wait until Task is finished in C#?

The other way to wait for the multiple tasks is using WhenAll method of the Task class. This method will return a task which will complete when all the task objects in the array have been completed. And if in case if you want to wait for only a single task to complete. You have to use WaitAny method of the Task class.

How do you return a value from a Task?

You want to return a task result to the client. Set the task's Result property with your user defined result object. The task's Result property is serialized and returned back to the client.

Is async await part of TPL?

Await & Async was built on the Task Parallel Library (TPL) which was introduced in the . NET Framework 4. Their purpose is to enable asynchronous programming.

What is task parallelism in C#?

The Task Parallel Library (TPL) is based on the concept of a task, which represents an asynchronous operation. In some ways, a task resembles a thread or ThreadPool work item but at a higher level of abstraction. The term task parallelism refers to one or more independent tasks running concurrently.


1 Answers

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;
}
like image 76
i3arnon Avatar answered Oct 11 '22 07:10

i3arnon