I have a method that creates some Tasks, and then waits on them with WaitAll before returning. The problem is, if those tasks got canceled, then WaitAll throws an AggregateException containing lots of TaskCanceledExceptions.
That means that WaitAll will throw exceptions in two different circumstances:
- Exceptions that indicate a genuine error. These mean that there was a condition we didn't know how to handle; they need to propagate as unhandled exceptions, until they eventually terminate the process.
- Exceptions that indicate that the user clicked a Cancel button. These mean that the task was canceled and cleaned up, and the program should continue running normally.
The latter fits squarely into the definition of a vexing exception: it's an exception thrown in a completely non-exceptional circumstance, so I have to catch it in order to resume normal control flow. Fortunately it's easy to catch, right? Just add catch (AggregateException)
and — oh wait, that's the same type that gets thrown when there's a fatal error.
I do need to wait for the tasks to finish running before I return (I need to know that they're no longer using their database connections, file handles, or anything else), so I do need the WaitAll or something similar. And if any of the tasks faulted, I do want those exceptions to propagate as unhandled exceptions. I just don't want exceptions for cancel.
How can I prevent WaitAll
from throwing exceptions for canceled tasks?
Best Answer
The
AggregateException
provides aHandle
method that can be used for these situations. If for example you want to ignoreTaskCanceledException
you can do:If all the exceptions are of type
TaskCanceledException
, theHandle
method will not throw any exception; otherwise a newAggregateException
containing only the unhandled exceptions will be thrown.