Answered by:
Why is unobserved exception not thrown when task has continuation

Question
-
I have following TPL code
using System; using System.Threading; using System.Threading.Tasks; class Program { static async Task<int> TestException() { await Task.FromResult(1); throw new ApplicationException(); } static void Run () { var t = TestException().ContinueWith(l => { }, TaskContinuationOptions.ExecuteSynchronously); t.Wait (); t = null; } static void Main() { Run (); GC.Collect (); GC.WaitForPendingFinalizers(); Console.WriteLine("Trying again"); GC.Collect (); GC.WaitForPendingFinalizers(); Console.ReadLine (); } }
There is clearly unobserved exception thrown but I cannot force .NET Framework to throw it. Removing the continuation fixes the issue and the exception is thrown by finalizer. What am I doing wrong that the exception is completely ignored.
Wednesday, May 2, 2012 2:28 PM
Answers
-
You're using .NET 4.5? See http://blogs.msdn.com/b/pfxteam/archive/2011/09/28/10217876.aspx
- Proposed as answer by Stephen Toub - MSFTMicrosoft employee, Moderator Tuesday, May 8, 2012 6:23 PM
- Edited by Stephen Toub - MSFTMicrosoft employee, Moderator Wednesday, May 23, 2012 4:50 PM Removed period from the end of the link
- Marked as answer by Stephen Toub - MSFTMicrosoft employee, Moderator Friday, August 24, 2012 6:09 AM
Tuesday, May 8, 2012 6:23 PMModerator
All replies
-
You're using .NET 4.5? See http://blogs.msdn.com/b/pfxteam/archive/2011/09/28/10217876.aspx
- Proposed as answer by Stephen Toub - MSFTMicrosoft employee, Moderator Tuesday, May 8, 2012 6:23 PM
- Edited by Stephen Toub - MSFTMicrosoft employee, Moderator Wednesday, May 23, 2012 4:50 PM Removed period from the end of the link
- Marked as answer by Stephen Toub - MSFTMicrosoft employee, Moderator Friday, August 24, 2012 6:09 AM
Tuesday, May 8, 2012 6:23 PMModerator -
The exception is not thrown by the finalizer its thrown by your wait call. By chaining the continueWith means you are waiting on the continuesWith generated task not the task that throws the exception. Since the ContinuesWith body doesn't throw an exception or attempt to get the result from the previous task then the framework as of 4.5 will just swallow the exception
Andrew Clymer www.rocksolidknowledge.com
Tuesday, May 8, 2012 7:45 PM -
I'm somehow agree with Andrew. Because you call t.Wait(), the exception will be raised. So it is not an unobserved exception. But I think this argument is not true:
If a task raises an exception and its continuation doesn't check its antecedent's result or Exception property, then the exception will be swallowed (became unobserved).
A exception in a task will be unobserved only none of the following conditions are met:
1. Its Wait() method is not called.
2. Its 'Result' property is read (if it is a Task<T>).
3. Its 'Exception' property is not read.
Hi Stephen. I get an HTTP 404 error for the link you've mentioned.
Monday, May 14, 2012 5:36 AM