Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Waiting on a Task with a OnlyOnFaulted Continuation causes an AggregateException

I have some simple code as a repro:

var taskTest = Task.Factory.StartNew(() => {     System.Threading.Thread.Sleep(5000);  }).ContinueWith((Task t) => {     Console.WriteLine("ERR"); }, TaskContinuationOptions.OnlyOnFaulted);  try {     Task.WaitAll(taskTest); } catch (AggregateException ex) {     foreach (var e in ex.InnerExceptions)         Console.WriteLine(e.Message + Environment.NewLine + e.StackTrace); } 

However, I'm getting an unexpected TaskCanceledException being thrown in the try catch block (it's in the AggregateException InnerExceptions object). "A task was canceled".

Why am I getting this exception? The Continuation for the task never fires, there was no exception generated by it, yet I still get the aggregate exception when waiting....

I'm hoping someone can explain how this makes sense to me :)

like image 782
Redth Avatar asked Jul 04 '11 15:07

Redth


People also ask

What is an AggregateException?

AggregateException is used to consolidate multiple failures into a single, throwable exception object. It is used extensively in the Task Parallel Library (TPL) and Parallel LINQ (PLINQ). For more information, see Exception Handling and How to: Handle Exceptions in a PLINQ Query.

How to handle exception in Task?

Exceptions are propagated when you use one of the static or instance Task. Wait methods, and you handle them by enclosing the call in a try / catch statement. If a task is the parent of attached child tasks, or if you are waiting on multiple tasks, multiple exceptions could be thrown.

How to handle exception in Task c#?

C# 4.0 and below. You can handle exceptions using the ContinueWith overload that takes a value from the TaskContinuationOptions enumeration, like so: // Get the task. var task = Task.


1 Answers

You're not waiting on a task with an OnlyOnFaulted continuation - you're waiting on that continuation (returned by ContinueWith). The continuation is never going to fire because the original task returned normally, so it's acting as if it were cancelled.

Makes sense to me.

I suspect you want to create the task, add the continuation, but then wait on the original task:

var taskTest = Task.Factory.StartNew(() => {     System.Threading.Thread.Sleep(5000);  }); taskTest.ContinueWith((Task t) => {     Console.WriteLine("ERR"); }, TaskContinuationOptions.OnlyOnFaulted); 
like image 194
Jon Skeet Avatar answered Sep 23 '22 16:09

Jon Skeet