7

I'm wondering how to use the Task.WaitAll overloads that take a CancellationToken as an argument, e.g. https://msdn.microsoft.com/en-us/library/dd321573%28v=vs.110%29.aspx

The documentation says the CancellationToken argument is "A CancellationToken to observe while waiting for the tasks to complete."

Since Task.WaitAll is a blocking operation, how could you possibly "observe" it during that operation? Furthermore, it says "The cancellationToken argument is used to cancel the wait operation. If it is canceled, the Wait returns false." but then it also says elsewhere that a OperationCanceledException is thrown when the CancellationToken is cancelled, meaning Task.WaitAll doesn't return true or false.

I'm either missing something really simple, or something is wrong with the documentation. Either way, I'm thoroughly confused. My ultimate goal is to be able to wait for multiple tasks to finish or to cancel them gracefully (via the proper use of CancellationToken) if they don't finish within a certain period of time.

This is related to my post here, but this time, I'm writing the async code and can observe the cancellation tokens.

14
  • Task.WaitAll is observing the token you pass to it. Commented Jan 28, 2015 at 13:25
  • @CodesInChaos -- so how is it ever cancelled then? Who cancels it? Commented Jan 28, 2015 at 13:32
  • Note that cancelling WaitAll doesn't cancel the individual tasks. You need to also pass the token to the tasks, and depending on the nature of the task, they also need to explicitly check if the token has been cancelled. Commented Jan 28, 2015 at 13:33
  • "Who cancels it?" -- Whoever calls CancellationTokenSource.Cancel() on its source. For timeouts this happens through a timer created by the source. Commented Jan 28, 2015 at 13:34
  • 1
    @roryap It is not that mainthread can cancel tasks. It could be any thread. To be precise whoever has a reference to CancellationTokenSource can cancel it. It is not necessarily main thread. Commented Jan 28, 2015 at 13:39

1 Answer 1

4

Since Task.WaitAll is a blocking operation, how could you possibly "observe" it during that operation?

You're not the one who observes it; it's the Task.WaitAll method that does.

Furthermore, it says "The cancellationToken argument is used to cancel the wait operation. If it is canceled, the Wait returns false." but then it also says elsewhere that a OperationCanceledException is thrown when the CancellationToken is cancelled, meaning Task.WaitAll doesn't return true or false.

It seems to be a mistake in the documentation. It returns false if the specified timeout elapses before the tasks complete or the wait is canceled.

Who cancels it?

Typically, some code running on another thread, since the current thread is already busy waiting for the tasks to complete. Or you could have called CancellationTokenSource.CancelAfter to specify a timeout after which the token is canceled.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks, this helps a lot. The one issue I have is that I've tested this by spawning a new thread that cancels the token, and instead of the Task.WaitAll returning false, an exception is thrown. So is that the actual issue with the documentation? It says it would return false, but it doesn't due to the exception.
@roryap, basically, yes. The doc is wrong, it's easily verifiable. I have already reported it with their feedback system, hopefully they'll fix it at some point.
It throws the exception if the token has been canceled (even if that cancellation was due to a timeout). It only returns false if the timeout you pass to WaitAll expires before either token gets canceled or all tasks complete.
@CodesInChaos -- "It only returns false if the timeout you pass to WaitAll expires before either token gets canceled or all tasks complete." -- then what timeout are you referring to in "It throws the exception if the token has been canceled (even if that cancellation was due to a timeout)"
@roryap You can (optionally) pass a timeout the the CancellationTokenSource and a separate timeout to WaitAll. The former results in an exception, the latter in false.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.