Reputation: 2178
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
Upvotes: 2
Views: 633
Reputation: 61666
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.
Upvotes: 1