try catch 在 WinForms 应用程序中无法正常工作

try catch not working properly in WinForms Application

我试图在遗留 winforms 应用程序中捕获异常,但不知何故,全局异常处理总是捕获该异常。

在Program.cs中我有以下代码:

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

Application.ThreadException += Application_ThreadException;
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
    //throw new NotImplementedException();
    MessageBox.Show(e.Exception.Message);
}

在表单中我有以下代码:

private void gttBindingSourceLosplaatsen_PositionChanged(object sender, EventArgs e)
{
    try
    {
        bool enabled = ((DataTable)gttBindingSourceLosplaatsen.DataSource).Rows.Count > 0;
        buttonEditLosplaats.Enabled = enabled;
        buttonDeleteLosplaats.Enabled = enabled;
    }
    catch 
    {
        MessageBox.Show("what is this ?");
    }
}

现在执行"buttonDeleteLosplaats.Enable = enabled;"行时出现异常。现在我希望落入 catch 块并显示消息 "What is this ?" 但那没有发生,我总是落入全局异常处理程序。

这可能是什么原因造成的?此应用程序中还有许多其他 try..catch 结构可以按我的预期工作并落入 catch 块,但不是这个。 有人知道为什么我不进入本地 try...catch 块而是进入全局异常处理程序吗?

您找到抛出此异常的代码的几率为零,Enabled 属性 无法抛出 "Index -1 does not have a value" 异常。

 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

这才是你真正的问题。为 Application.ThreadException 编写事件处理程序很好,但只有在不需要调试程序时才有效。在 UnhandledExceptionMode.CatchException 激活的情况下,当程序抛出时你会变得非常盲目。调试器无法再停止并向您显示问题,现在是您的 ThreadException 事件处理程序吞下了它。从技术上讲,您仍然可以让它停止,您需要使用 Debug + Exceptions,勾选 CLR 异常的 Thrown 复选框。

但正确的解决方法是,调试时不要启用此事件处理程序。修复:

    if (!System.Diagnostics.Debugger.IsAttached) {
        Application.ThreadException += Application_ThreadException;
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
    }

您正在捕获所有未处理的异常,请尝试指定异常类型(或泛型)。如果您捕获无法处理指定的异常类型,则会发生抛出。

try
{
    bool enabled = ((DataTable)gttBindingSourceLosplaatsen.DataSource).Rows.Count > 0;
    buttonEditLosplaats.Enabled = enabled;
    buttonDeleteLosplaats.Enabled = enabled;
}
catch (Exception ex)
{
    MessageBox.Show("what is this ?");
}

我通过将代码更改为以下解决了我的问题:

gttTextBoxLotnr.Focus();
this.ActiveControl = gttTextBoxLotnr;

bool enabled = ((DataTable)gttBindingSourceLosplaatsen.DataSource).Rows.Count > 0;
buttonEditLosplaats.Enabled = enabled;
buttonDeleteLosplaats.Enabled = enabled;

现在异常 "Index -1 does not have a value" 不再发生,我不再需要 try catch。 buttonDeleteLosplaats 有 Focused 属性 = true 并且在将启用的 属性 设置为 false 时以某种方式导致异常。

这仍然给我留下了 2 个可能永远无法回答的问题:

  1. 我仍然不知道为什么我的 catch 条款没有达到
  2. 将焦点控件的启用 属性 设置为 false 会引发异常,为什么需要这样做?我想不出有什么情况严重到可以抛出异常,表单应该没有活动控件,就是这样,没有造成伤害,在任何宇宙中的任何地方都没有问题,那么为什么要抛出异常?