2

My application has global exception handlers (ok, loggers, I know they don't technically "handle" them) which are simply something like:

public static class UnhandledExceptionHandler { public static void Init() { AppDomain.CurrentDomain.UnhandledException += OnCurrentDomainOnUnhandledException; Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); Application.ThreadException += ApplicationOnThreadException; } private static void ApplicationOnThreadException(object sender, ThreadExceptionEventArgs e) { if (e.Exception != null) MessageBox.Show(e.Exception.ToString()); } private static void OnCurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e) { var ex = e.ExceptionObject as Exception; if (ex != null) MessageBox.Show(ex.ToString()); } } 

In Main() is

UnhandledExceptionHandler.Init(); 

But I am finding that when unhandled exceptions occur within a Task.ContinueWith these events are not raised. Visual Studio recognises them as unhandled as they are highlighted in the debugger.

For example, you can test this with simply:

private void button1_Click(object sender, EventArgs e) { Task.Factory.StartNew(() => { }) .ContinueWith(t => { throw new Exception("continue with exception"); }); } 

You will notice that no MessageBox gets raised (nor are either of the events raised).

Just to prove it does work, the following will work:

private void button2_Click(object sender, EventArgs e) { throw new Exception("click failed"); } 

Anyone have any ideas why and/or how I might be able to catch and log these unhandled exceptions?

Of course, I appreciate that it would probably make sense to keep the amount of logic inside of the ContinueWith to a minimum, but it may still occur.

This is currently .NET 4.0

4
  • Task.Factory.StartNew/ContinueWith returns a Task which has a Exception property. Commented Feb 19, 2014 at 11:34
  • Ok, but would that not mean in my example above I would then have to have another ContinueWith which I then check t.Exception? Would I then need an infinite number of ContinueWith's just in case :) Commented Feb 19, 2014 at 11:41
  • Writing an infinite number of ContinueWiths only makes sense if you take your user name too seriously. Using the overload that takes TaskContinuationOptions.OnlyOnFaulted tends to be useful. Do avoid writing fire-and-forget code. Commented Feb 19, 2014 at 11:47
  • It's a shame though that I have to append a ContinueWith with OnlyOnFaulted to a Task after any other ContinueWiths in order to ensure I handle exceptions. Commented Feb 19, 2014 at 11:52

1 Answer 1

1

From the comments:

It's a shame though that I have to append a ContinueWith with OnlyOnFaulted to a Task after any other ContinueWiths in order to ensure I handle exceptions.

You don't have to. Just use the Then pattern by Stephen Toub from "Processing Sequences of Asynchronous Operations with Tasks". Also, make sure to read "Tasks and Unhandled Exceptions", it will help to better understand the behavior you're seeing.

That said, you may want to seriously consider using Microsoft.Bcl.Async and async/await, if you code with VS2012+. This will make you forget about ContinueWith, and use natural try/catch for handling exceptions.

Sign up to request clarification or add additional context in comments.

1 Comment

Whilst this doesn't answer my question, this really helps to understand the way that ContinueWith returns a new* Task which when combined with OnlyOnFaulted will only execute upon failure. Therefore chaining these ContinueWiths do not behave as expected.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.