有人可以解释如何正确处理应用程序范围异常

时间:2011-03-08 18:59:05

标签: c# .net

我似乎不能正确地说明我应该如何正确处理意外的异常。

考虑以下应用程序:

[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");
    }
}

如果我运行此应用程序并单击按钮,我会得到一个未处理的异常。起初我尝试使用try catch块围绕Application.Run,​​如下所示:

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

起初这似乎有效,直到我在调试器外部运行应用程序。在调试器外部运行应用程序时,异常将报告为未处理的错误。在做了一些阅读之后,我发现我应该查看Application.ThreadException事件。所以我做了以下几点:

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");
}

现在,当我在调试器外部运行我的应用程序时,会处理异常并且MessageBox指示它已在事件处理程序中捕获。然后我回到调试器并运行它。现在调试器将它作为未处理的异常启动,即使我已经在try catch中包围它并且我绑定到Application.ThreadException事件。如果我没有绑定到Application.ThreadException事件,那么try catch块会正确捕获异常。

现在回答问题:

  1. 到底发生了什么事?
  2. 有没有办法可以捕获/处理我的应用程序中的所有异常,这些异常在调试器和调试器之外都有效?
  3. 我在这里做错了吗?

2 个答案:

答案 0 :(得分:3)

您可以使用AppDomain.CurrentDomain.UnhandledExceptionApplication.ThreadExceptionlook for more来处理它们。

答案 1 :(得分:3)

  1. 调试器将传播到Application_ThreadException的异常视为未处理的异常,因为该事件处理程序用作正常记录和终止的最终位置。这允许您在运行调试器时停止在异常点,这通常非常有用。

  2. 在一个全局位置处理所有异常是不可能的,因为没有足够的上下文来知道如何实际处理它们。您可以使用Application_ThreadException(以及其他线程上的异常的AppDomain.UnhandledException)捕获所有异常(甚至是未处理的异常),但在这种情况下您应该做的下一步是关闭您的应用程序。

  3. 您应该根据您拥有的信息以及可能发生的异常类型的知识,分别处理每种方法中的异常。不应该捕获您不知道如何处理的异常,并且将渗透到“全局”事件处理程序,这些处理程序应记录详细信息并礼貌地关闭应用程序。