Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does overloaded version of Task.WaitAny Cancel the task?

int WaitAny(Task[] tasks, int millisecondsTimeout); 

Does the above method cancel the task after the timeout period? It looks it doesn't but C# 70-483 exam reference book says this overloaded version cancel the task. Here is some test code,

Task longRunning = Task.Run(() =>
{
    Thread.Sleep(10000);
});
int index = Task.WaitAny(new Task[] { longRunning }, 1000); // returns -1
index = 0; // reset it to reuse in the loop
while (index < 12)
{
    Thread.Sleep(1000);
    index++;
    Console.WriteLine("long running task status {0}", longRunning.Status);
}

First few times, Status is Running and after that the status change to RanToCompletion. So what that time out does related to Task and WaitAny?

like image 243
RotatingWheel Avatar asked Nov 04 '15 11:11

RotatingWheel


1 Answers

Task.WaitAny will complete if either (a) any of tasks it wraps complete or (b) the timeout is exceeded. If the timeout is exceeded, WaitAny completes, but the tasks it wraps will not be cancelled. Cancellation with tasks tends to be cooperative rather than implicit, and will involve the explicit passing of a CancellationToken.

If you want the task to cancel after a timeout you can create a CancellationTokenSource with a timeout and pass that into the task you're waiting for:

 using(CancellationTokenSource cts=new CancellationTokenSource(TimeSpan.FromSeconds(5)))
{
    var task = Task.Delay(TimeSpan.FromSeconds(10), cts.Token);
    task.Wait();
}

Of course, waiting for tasks to complete using blocking methods is highly discouraged, as is wrapping synchronous blocking code in Task.Run and expecting everything to work correctly and "asynchronously".

Embrace async/await for the win.

like image 93
spender Avatar answered Oct 31 '22 14:10

spender