Is it a valid use of CancellationToken.Cancel()
to cancel other tasks running in parallel if one of the tasks throws an exception? For example:
using var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
try
{
var tasks = new List<Task>();
tasks.Add(SomeDbContextBasedTaskAsync(token));
...
tasks.Add(SomeDbContextBasedTaskAsync(token));
Task.WaitAll(tasks.ToArray(), token);
}
catch (Exception ex)
{
tokenSource.Cancel(); // Cancel any other tasks that are still in flight
}
Or is this an anti-pattern that could lead to issues? It seems a good application to me, but I haven't found any examples of the CancellationToken
being used in this way, and a fellow developer I discussed it with felt that issues could occur applying the Cancel()
from the catch block.
In my real-world application I'm making calls to DbContext
based functionality that should pick up the CancellationToken
and respond appropriately to it, rather than me needing to implement any hand-rolled cancellation code.
This question is subtly different to Cancel all async methods if one throws an exception as we're not await
'ing every call in order. Here we're capturing a list of Task
, all of which are in-flight when anyone of them may fail, throwing an exception. This list is only Task.WaitAll
'd once all tasks are in-flight asynchronously.
The purpose of the Cancel()
in this case it to prevent needless database calls from continuing after an exception has been detecting in any of the calls. Hopefully saving a bit of resource consumption.