【问题标题】:Can someone please explain how to Handle Application Wide Exceptions properly有人可以解释如何正确处理应用程序范围的异常吗
【发布时间】:2011-07-11 08:30:47
【问题描述】:

我似乎无法正确处理意外异常。

考虑以下应用:

[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. 我在这里做错了吗?

【问题讨论】:

    标签: c# .net


    【解决方案1】:

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

    【讨论】:

    • 我看过了,但它并没有解决我的问题。如果我绑定到任一事件处理程序,调试器仍会将异常报告为未处理并且不会执行处理程序。
    • @Matthew,异常 is 未处理,因此获得预期行为的唯一方法是告诉调试器不要停止用户未处理的异常。被触发的事件不是异常处理程序,而只是一个通知发生未处理异常的地方。
    • 检查您的调试设置 |由调试器控制异常类型的异常。
    • 我显然找到了答案,诀窍是转到工具->选项->调试->仅启用我的代码调试器创建一个不同的堆栈来运行并在堆栈被清除时调用您的进程它没有看到异常将在下一个堆栈上处理......或类似的东西
    【解决方案2】:
    1. 调试器将传播到 Application_ThreadException 的异常视为未处理的异常,因为该事件处理程序被用作记录和正常终止的最终位置。这允许您在运行调试器时在异常点停止,这通常很有帮助。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-10
      • 1970-01-01
      • 1970-01-01
      • 2010-11-17
      • 2011-05-05
      • 2021-03-04
      • 2011-09-05
      • 2012-07-09
      相关资源
      最近更新 更多