1

I am using the Task Parallel Library for .NET 3.5 (a NuGet package).

When running the following code, the OnlyOnFaulted task is not being run when an exception is thrown from MethodThrowsException():

var task = Task.Factory.StartNew<SomeType>(() =>
{
    MethodThrowsException();
})
.ContinueWith(t =>
{
    ExceptionMessageTextBox.Text = t.Exception.Message;
},
CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.FromCurrentSynchronizationContext());

I (eventually) get this exception:

System.AggregateException was unhandled
Message: An unhandled exception of type 'System.AggregateException' occurred in System.Threading.dll
Additional information: TaskExceptionHolder_UnhandledException

AggregateException was unhandled

I cannot see where it is located as it is being thrown within System.Threading.dll (I would need to load the pdb).

As far as I can see, I am observing the exception correctly, as specified by this MSDN article.

Dave New
  • 38,496
  • 59
  • 215
  • 394
  • How are you encountering the exception? Is this being run with the debugger? – theMayer Dec 10 '14 at 15:33
  • @theMayer: Visual Studio 2013 reports the exception as unhandled in System.Threading.dll. Added screenshot. – Dave New Dec 10 '14 at 15:36
  • Do you have "Just my code" turned on? If so, it will report exceptions as "unhandled" because they are not handled by "your code". Turn this feature off--it is not useful. – Matt Smith Dec 10 '14 at 15:49
  • @MattSmith: "Just my code" is indeed off. – Dave New Dec 11 '14 at 07:00
  • What happens if you attempt to continue and let the exception propagate? This really smells like a bug with .Net if it's not due to the nature of how the debugger works (which I think it is). **Edit** I saw the post by @MattSmith - you need to turn "Just my code" on. I suspect this will go away at that point, but let us know. – theMayer Dec 11 '14 at 11:54
  • Is there other code dealing with Tasks? How do you know the exception is related to this code? This appears to be the exception that occurs when you let a Task get finalized that didn't have its Exception observed. – Matt Smith Dec 11 '14 at 13:48
  • @MattSmith: No other tasks whatsoever. The exception must be related to this code as far as I can understand. If I replace `MethodThrowsException()` with `throws Exception()` the same problem arises. Thanks for your help. – Dave New Dec 12 '14 at 08:01
  • 1
    Are you sure it is not the continuation that is causing the problem? I.e. put a try/catch all around the code inside the ContinueWith. Are you able to see what the InnerException of the AggregateException is? – Matt Smith Dec 12 '14 at 13:56
  • 1
    @MattSmith: 100% correct. The ContinueWith is not running on my UI thread so setting the control property threw an exception. I can't get this working, so I'm just using Dispatch (ugh). Thanks – Dave New Dec 12 '14 at 14:00
  • Is this Winforms? Where is this code running from? A click handler? I assume that in the place where it is running from if you check SynchronizationContext.Current that it is null? You can make this work if you figure out why SynchronizationContext.Current is null when it should be a WindowsFormsSynchronizationContext. – Matt Smith Dec 12 '14 at 14:06

1 Answers1

-1

So I know this question is pretty old, but I encountered this same problem today, and this question was the only one that I could find related to this issue on StackOverflow. I'm going to add my solution in hopes it helps someone else in the same situation.

The problem here is that the thrown exception is not actually being handled by the continuation. The exception(s) thrown within the task remain unhandled individually, therefore we must actually handle them. Include the code below inside the continuation and it should resolve the issue:

backgroundTask.ContinueWith(t =>
{
    if (t.Exception != null)
    {
        var flattenedExceptions = t.Exception.Flatten();
        flattenedExceptions.Handle((exp) => {
            // process each exception here
            return true;
        });
    }

}, TaskContinuationOptions.OnlyOnFaulted);

More information here at the MSDN documentation.