I am using the following event to catch unhandled exceptions in the main UI thread.
Application.ThreadException
Unfortunately, it does not
Yes, you have to manually catch exceptions on threads.
However, this code:
void ThreadMethod(object state)
{
try
{
ActualWorkerMethod();
}
catch (Exception err)
{
_logger.Error("Unhandled exception in thread.", err);
}
}
void ActualWorkerMethod()
{
// do something clever
}
can be simplified to this using PostSharp:
[LogExceptions]
void ActualWorkerMethod()
{
// do something clever
}
@Ani have already answered your question. Although I don't agree that unhandled exceptions in threads should terminate applications. Using threads usually means that you have some kind of server application. Bringing it down could result in a lot of angry users.
I've written a small piece about proper exception handling: https://coderr.io/exception-handling
You should always catch exceptions for threads. I usually use the following pattern:
void ThreadMethod(object state)
{
try
{
ActualWorkerMethod();
}
catch (Exception err)
{
_logger.Error("Unhandled exception in thread.", err);
}
}
void ActualWorkerMethod()
{
// do something clever
}
It's a whole lot easier to find thread methods that doesn't handle exceptions properly by moving the logic into a seperate method and just keep the try/catch block in the thread method.
Of course you should always handle all exceptions. But if you are currently incapable of doing so, you can try the following:
The application will crash/close after the UnhandledException
event handler.
You can just add a delay in the event handler to prevents this. Other threads with no exception (e.g. the main thread) can continue. So the application will not close and can continue. However, the thread with the exception will remain in sleep. And therefor you may get a "memory/thread leak".
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
// Log the exception, display it, etc
Debug.WriteLine((e.ExceptionObject as Exception).Message);
Thread.Sleep(100000000);
}
At this moment there is not a better solution. You may find to change the config file, but i think that is just as dirty: https://stackoverflow.com/a/15348736