Just for a future reference - suppose a task should not take longer than ... but there's still a need to finish it. It's just the caller that cannot wait longer
One of use cases involves a REST service where you provide the server part. There's a client that should get an answer in max X seconds, regardless of whether the actual task finishes or not.
You want a timer that runs together with the task and in case any of the two finishes first, you want to know which one was it.
Let's stage actors first:
public class TaskExperiments { public async Task<string> DelayWithEcho( int ms, string echo, string id ) { await Task.Delay( ms ); Console.WriteLine( echo ); return id; } }
This one above is supposed to be a factory of tasks. A task is given a time and an id so that when it finishes, I know the id.
Now, the runner:
var e = new TaskExperiments(); var t1 = e.DelayWithEcho( 5000, "Task1 after 5000ms - time constraint", "i1" ); var t2 = e.DelayWithEcho( 3000, "Task2 after 3000ms - actual task", "i2" ); var t = await Task.WhenAny( t1, t2 ); var id = await t; Console.WriteLine( $"Finished one of the two : {id}" );
As you can see, Task.WhenAny is used and then the result task is awaited once again to get the id.
Running this gives:
Task2 after 3000ms - actual task Finished one of the two : i2 Task1 after 5000ms - time constraint
Now change the second to last longer:
... var t2 = e.DelayWithEcho( 7000, "Task2 po 7000ms - actual task", "i2" ); ...
and the result is
Task1 after 5000ms - time constraint Finished one of the two : i1 Task2 after 7000ms - actual task