简体   繁体   中英

Can someone please explain how to Handle Application Wide Exceptions properly

I cant seem to make heads or tails of how I am supposed to properly handle unexpected exceptions.

Consider the following application:

[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new SomeForm());
}

class SomeForm : Form
{
    public SomeForm()
    {
        Button btn = new Button();
        btn.Text = "Click ME";
        btn.Location = new System.Drawing.Point(20, 20);
        btn.Click += new EventHandler(btn_Click);
        Controls.Add(btn);
    }

    void btn_Click(object sender, EventArgs e)
    {
        throw new Exception("This is an Exception");
    }
}

If I run this application and click the button I get an unhandled exception as expected. At first I tried surrounding the Application.Run with a try catch block like so:

    try { Application.Run(new SomeForm()); }
    catch { MessageBox.Show("Exception caught in try catch"); }

At first this seems to work, until I ran the application outside of the Debugger. When you run the application outside of the Debugger, the exception is reported as an unhandled error. After doing some reading I discovered I should be looking at the Application.ThreadException event. So I do the following:

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
    try { Application.Run(new SomeForm()); }
    catch { MessageBox.Show("Exception caught in try catch"); }
}

static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
    MessageBox.Show("Exception caught in event");
}

Now when I run my application outside of the debugger the exception is handled and the MessageBox indicates it was caught in the event handler. Then I go back into the debugger and run it. Now the Debugger kicks it up as an unhandled exception even though I have surrounded it in a try catch AND I am tied onto the Application.ThreadException event. If I do not tie up the to Application.ThreadException event the exception is caught correctly by the try catch block.

Now to the questions:

  1. What the heck is going on here?
  2. Is there a way that I can catch/handle all exceptions in my application that works both in the debugger and outside of the debugger?
  3. Am I just doing the completely wrong thing here?

You can handle them using AppDomain.CurrentDomain.UnhandledException and Application.ThreadException , look for more .

  1. The debugger considers exceptions that propagate to Application_ThreadException to be unhandled exceptions, since that event handler is used as a final location to log and terminate gracefully. This allows you to stop at the point of the exception when running the debugger, which is often very helpful.

  2. It's not possible to handle all exceptions in one global place because there is not enough context to know how to actually handle them. You can catch all exceptions (even the unhandled ones) using Application_ThreadException (and AppDomain.UnhandledException for exceptions on other threads), but the next thing you should do in that case is shut down your application.

  3. You should handle exceptions in each method separately, based on the information you have and the knowledge of the types of exceptions that can occur. Exceptions you don't know how to handle should not be caught and will percolate to the 'global' event handlers, which should log the details and politely shut down the application.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM