115

Alright, this is an easy one:

  • What's the difference between Application.ThreadException and
    AppDomain.CurrentDomain.UnhandledException?

  • Do I need to handle both?

Thanks!

serhio
  • 28,010
  • 62
  • 221
  • 374
JohnIdol
  • 48,899
  • 61
  • 158
  • 242

4 Answers4

113

Application.ThreadException is specific to Windows Forms. Winforms runs event handlers in response to messages sent to it by Windows. The Click event for example, I'm sure you know them. If such an event handler throws an exception then there's a back-stop inside the Winforms message loop that catches that exception.

That backstop fires the Application.ThreadException event. If you don't override it, the user will get a ThreadExceptionDialog. Which allows him to ignore the exception and keep running your program. Not a great idea btw.

You can disable this behavior by calling Application.SetUnhandledExceptionMode() in the Main() method in Program.cs. Without that backstop in place, the usual thing happens when a thread dies from an unhandled exception: AppDomain.UnhandledException fires and the program terminates.

Fwiw: "ThreadException" was a very poor name choice. It has nothing to do with threads.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • And how to stop WinForms application from crashing on the occurrence of `Application.ThreadException`. I raised a question for this [[here](http://stackoverflow.com/questions/23153287/suppressing-application-threadexception-and-appdomain-currentdomain-unhandledexc)] with my small C# code. – Mahesha999 Apr 18 '14 at 11:40
  • 5
    I always read it as Application-thread exception, given that winforms is bound to a single thread. – Gusdor Apr 25 '14 at 07:07
38

From source:

In applications that use Windows Forms, unhandled exceptions in the main application thread cause the Application.ThreadException event to be raised. If this event is handled, the default behavior is that the unhandled exception does not terminate the application, although the application is left in an unknown state. In that case, the UnhandledException event is not raised. This behavior can be changed by using the application configuration file, or by using the Application.SetUnhandledExceptionMode method to change the mode to UnhandledExceptionMode.ThrowException before the ThreadException event handler is hooked up. This applies only to the main application thread. The UnhandledException event is raised for unhandled exceptions thrown in other threads.

Starting with Visual Studio 2005, the Visual Basic application framework provides another event for unhandled exceptions in the main application thread - WindowsFormsApplicationBase.UnhandledException. This event has an event arguments object with the same name as the event arguments object used by AppDomain.UnhandledException, but with different properties. In particular, this event arguments object has an ExitApplication property that allows the application to continue running, ignoring the unhandled exception (and leaving the application in an unknown state). In that case, the AppDomain.UnhandledException event is not raised.

Application.ThreadException can be caught and the application could continue (in general is not a great idea, but for the application like running periodically some actions this is a good solution).

To catch exceptions that occur in threads not created and owned by Windows Forms, use the AppDomain.UnhandledException. It allows the application to log information about the exception before the system default handler reports the exception to the user and terminates the application.
The handling of this exception does not prevent application to be terminated.
The maximum that could be done(program data can become corrupted when exceptions are not handled) is saving program data for later recovery. After that the application domain is unloaded and the application terminates.

Starting with the .NET 4, this event is not raised for exceptions that corrupt the state of the process, such as stack overflows or access violations, unless the event handler is security-critical and has the HandleProcessCorruptedStateExceptionsAttribute attribute.

For more details, see MSDN.

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
serhio
  • 28,010
  • 62
  • 221
  • 374
21

OK - I had it in front of me, this bit of code from msdn is pretty self-explanatory:

public static void Main(string[] args)
{
    // Add the event handler for handling UI thread exceptions to the event.
    Application.ThreadException += new 
        ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);

    // Set the unhandled exception mode to force all Windows Forms 
    // errors to go through our handler.
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException +=
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    // Runs the application.
    Application.Run(new ErrorHandlerForm());
}
serhio
  • 28,010
  • 62
  • 221
  • 374
JohnIdol
  • 48,899
  • 61
  • 158
  • 242
  • 3
    this is in contrast with the other answer of serhio when he says: UnhandledExceptionMode.ThrowException should be set before the ThreadException event handler is hooked up. Not sure if the order really matters... – Davide Piras Sep 29 '11 at 08:26
  • @DavidePiras yes, and there's something more murky. SetUnhandledException seem to make no difference in my case. – nawfal Jan 07 '14 at 09:03
0

Well the thing is, ThreadException occurs due to a problem with your thread, the Unhandled Exception is fired if you code throws an exception that is not handled.

Easist way to cause the second one is to create an app with no try...catch blocks and throw an exception.

Now if you need insurance you can handle them both, however if you capture and handle your exceptions correctly then you should not need the UnhandledException handler as it's kind of like a catch all.

Sumit Pathak
  • 671
  • 1
  • 6
  • 25
Joshua Cauble
  • 1,349
  • 8
  • 7
  • thanks - what I was not too clear about was if handling UnhandledException I would catch also ThreadException - which seems not to be the case – JohnIdol Jan 06 '10 at 17:02