How to catch exceptions from a ThreadPool.QueueUserWorkItem?

I have the following code that throws an exception:

ThreadPool.QueueUserWorkItem(state => action());

When the action throws an exception, my program crashes. What is the best practice for handling this situation?


Related: Exceptions on .Net ThreadPool Threads


Solution 1:

You can add try/catch like this:

        ThreadPool.QueueUserWorkItem(state =>
                                         {
                                             try
                                             {
                                                 action();
                                             }
                                             catch (Exception ex)
                                             {
                                                 OnException(ex);
                                             }
                                         });

Solution 2:

If you have access to action's source code, insert a try/catch block in that method; otherwise, create a new tryAction method which wraps the call to action in a try/catch block.

Solution 3:

If you're using .Net 4.0, it might be worth investigating the Task class because it can take care of this for you.

The equivalent of your original code, but using Tasks, looks like

Task.Factory.StartNew(state => action(), state);

To deal with exceptions you can add a continuation to the Task returned by StartNew. It might look like this:

var task = Task.Factory.StartNew(state => action(), state);
task.ContinueWith(t => 
     {
        var exception = t.Exception.InnerException;
        // handle the exception here
        // (note that we access InnerException, because tasks always wrap
        // exceptions in an AggregateException)
     }, 
     TaskContinuationOptions.OnlyOnFaulted);