Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does Task.Run(Action, CancellationToken) throw TaskCanceledException?

According to documentation Task.Run(Action, CancellationToken) throws TaskCanceledException when the task has been canceled.

When exactly does Task.Run(Action, CancellationToken) throw TaskCanceledException? It is not clear what conditions must be met for this exception to be thrown.

like image 620
Alex Avatar asked Nov 28 '14 22:11

Alex


1 Answers

There seems to be some confusion (and the documentation might be misleading).

Inoking the Task.Run method would never throw TaskCanceledException (at least with the current implementation). Unlike ArgumentNullException and ObjectDisposedException that are thrown synchronously when the "The action parameter was null" and "The CancellationTokenSource associated with cancellationToken was disposed." respectively.

Task.Run however returns a Task that may be canceled using the CancellationToken parameter (more on cancellation in here) and waiting on it with await task, task.Wait(), task.Result, etc. would throw a TaskCanceledException (possibly wrapped in an AggregateException)

Task<int> task = null;
try
{
    task = Task.Run(() => 5, new CancellationToken(true));
}
catch (TaskCanceledException)
{
    Console.WriteLine("Unreachable code");
}

try
{
    int result = await task;
}
catch (TaskCanceledException)
{
    Console.WriteLine("Awaiting a canceled task");
}

It might be clearer if the documentation had 2 sections of possible exceptions:

  1. "regular" synchronous exceptions (e.g. ArgumentNullException and ObjectDisposedException)
  2. "async" asynchronous exceptions that could only be thrown by waiting on the returned task (e.g. TaskCanceledException)
like image 132
i3arnon Avatar answered Oct 07 '22 09:10

i3arnon