Home > .NET > Handle all uncaught exceptions thrown when using Task Parallel Library (take 2)

Handle all uncaught exceptions thrown when using Task Parallel Library (take 2)

A couple of days ago I posted a solution to handle all uncaught exceptions when using TPL. I’ve found a better way to do that, making use of task continuation. The class ThreadFactory below exposes the Error event which can be subscribed by a top-level handler and provides methods to start a task attached with proper continuation.

internal class ThreadFactory
{
    public delegate void TaskError(Task task, Exception error);

    public static readonly ThreadFactory Instance = new ThreadFactory();

    private ThreadFactory() {}

    public event TaskError Error;

    public void InvokeError(Task task, Exception error)
    {
        TaskError handler = Error;
        if (handler != null) handler(task, error);
    }

    public void Start(Action action)
    {
        var task = new Task(action);
        Start(task);
    }

    public void Start(Action action, TaskCreationOptions options)
    {
        var task = new Task(action, options);
        Start(task);
    }

    private void Start(Task task)
    {
        task.ContinueWith(t => InvokeError(t, t.Exception.InnerException),
                            TaskContinuationOptions.OnlyOnFaulted |
                            TaskContinuationOptions.ExecuteSynchronously);
        task.Start();
    }
}
Categories: .NET Tags: , , ,
  1. February 19th, 2011 at 09:33 | #1

    There’s a post about the problem http://blogs.msdn.com/b/pfxteam/archive/2009/05/31/9674669.aspx. Looks like your solution is the only one.

  2. March 1st, 2011 at 05:48 | #2

    Great stuff. Thank you!

  3. jlafay
    November 2nd, 2011 at 02:13 | #3

    There is also a method to trap and deal with AggregateExceptions that’s scoped to your AppDomain. I tend to prefer it because I don’t need a wrapper and I can handle any exceptions that get bubbled up from the Task and avoid my other exception handling mechanisms.

    The TaskScheduler.UnobservedTaskException event can be listened to. Likewise, you can set the AggregateException as “observed” so it doesn’t kill your process/application.

    The MSDN for the event is here http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler.unobservedtaskexception.aspx.

    It’s usage could be something like this:

    TaskScheduler.UnobservedTaskException += (sender, args) =>
    {
    // process whatever you need to handle the exception.
    // all of the unhandled exceptions are found in
    // the args.Exception.InnerExceptions collection

    // make sure to set it as observed if you want to prevent your application from crashing
    args.SetObserved();
    };

    Just my two cents.

  1. No trackbacks yet.