Brendan Hill
Brendan Hill

Reputation: 3742

Why does subscription to Application.ThreadException swallow the exception?

Suppose I have an exception throw in the message loop:

    private void timer1_Tick(object sender, EventArgs e)
    {
        throw new Exception("yehaaaa!!!!");
    }

By default, this throws & displays the generic error dialog to user. (that's what I want)

However if I add the following subscription to Application.ThreadException:

    Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);

    private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
        //_raygunClient.Send(e.Exception);
    }

Then the exception is swallowed.

Why?

& how can I have it throw to the user normally?

Upvotes: 0

Views: 174

Answers (1)

Mike Zboray
Mike Zboray

Reputation: 40818

It's all right there in the reference source:

internal void OnThreadException(Exception t) {
    if (GetState(STATE_INTHREADEXCEPTION)) return;

    SetState(STATE_INTHREADEXCEPTION, true);
    try {
        if (threadExceptionHandler != null) {
            threadExceptionHandler(Thread.CurrentThread, new ThreadExceptionEventArgs(t));
        }
        else {
            if (SystemInformation.UserInteractive) {
                ThreadExceptionDialog td = new ThreadExceptionDialog(t);

If there is a handler it is invoked otherwise some standard code is run. If you want to show the standard dialog, use ThreadExceptionDialog and handle the DialogResult the same way. In my own code there is something to this effect, which seems to work:

private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
    Exception exception = e.Exception;
    _Logger.Error(e.Exception, "An unhandled forms application exception occurred");

    // Show the same default dialog
    if (SystemInformation.UserInteractive)
    {
        using (ThreadExceptionDialog dialog = new ThreadExceptionDialog(exception))
        {
            if (dialog.ShowDialog() == DialogResult.Cancel)
                return;
        }

        Application.Exit();
        Environment.Exit(0);
    }
}

Upvotes: 2

Related Questions