locked
Why is unobserved exception not thrown when task has continuation RRS feed

  • 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

All replies

  • Tuesday, May 8, 2012 6:23 PM
    Moderator
  • 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