事件的异常处理

Jus*_*ing 6 c# exception-handling winforms

如果这是一个简单的问题,我很抱歉(我的谷歌今天可能很糟糕).

想象一下这个WinForms应用程序,它具有这种类型的设计:主应用程序 - >显示一个对话框 - >第一个对话框可以显示另一个对话框.两个对话框都有OK/Cancel按钮(数据输入).

我试图找出某种类型的全局异常处理,沿着Application.ThreadException.我的意思是:

每个对话框都有一些事件处理程序.第二个对话框可能包含:

private void ComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
    try
    {      
        AllSelectedIndexChangedCodeInThisFunction();
    }
    catch(Exception ex)
    {
        btnOK.enabled = false;  // Bad things, let's not let them save
        // log stuff, and other good things
    }
}
Run Code Online (Sandbox Code Playgroud)

实际上,此对话框中的所有事件处理程序都应以这种方式处理.这是一个例外情况,所以我只想记录所有相关信息,显示消息,并禁用该对话框的okay按钮.

但是,我想避免在每个事件处理程序中使用try/catch(如果可以的话).所有这些try/catch的缺点是这样的:

private void someFunction()
{
    // If an exception occurs in SelectedIndexChanged,
    // it doesn't propagate to this function
    combobox.selectedIndex = 3; 
}
Run Code Online (Sandbox Code Playgroud)

我不相信Application.ThreadException是一个解决方案,因为我不希望异常一直回到第一个对话框,然后是主应用程序.我不想关闭应用程序,我只想记录它,显示一条消息,让它们从对话框中取消.他们可以决定从那里做什么(也许去应用程序的其他地方).

基本上,第一个对话框和第二个对话框之间的"全局处理程序"(然后,我想,主应用程序和第一个对话框之间的另一个"全局处理程序").

Han*_*ant 8

是的,Application.ThreadException的默认处理是一个错误.不幸的是,这是一个必要的错误,不需要立即阻止和绝望成千上万的程序员编写他们的第一个Windows窗体应用程序.

你正在考虑的修复不是一个修复,它有很大的潜力,使它变得更糟.当用户单击异常对话框上的"继续"按钮是一个值得怀疑的结果时,吞噬全局异常处理程序中的异常会更糟糕.

是的,为ThreadException编写替换处理程序.让它在消息框中显示e.Exception.ToString()的值,以便用户知道爆炸的内容.然后触发电子邮件或附加到错误日志,以便知道出了什么问题.然后调用Environment.FailFast(),这样就不会再造成任何损害.

对AppDomain.CurrentDomain.UnhandledException执行相同操作.它不会得到很多锻炼.

使用反馈来改进您的代码.您将找到需要验证的位置.您可以帮助客户的IT人员诊断LAN和设备的故障.并且您会发现极少数情况下您自己的try/catch块可能能够从异常中恢复.


LBu*_*kin 1

您可以使用AppDomain.CurrentDomain.UnhandledException处理程序拦截主 UI 线程上的错误并按对话框处理它们。来自 MSDN:

在使用 Windows 窗体的应用程序中,主应用程序线程中未处理的异常会导致 Application.ThreadException引发该事件。如果处理此事件,则默认行为是未处理的异常不会终止应用程序,尽管应用程序仍处于未知状态。在这种情况下, UnhandledException不会引发该事件。可以通过使用应用程序配置文件或使用将 Application.SetUnhandledExceptionMode 模式更改为 连接事件处理程序UnhandledExceptionMode.ThrowException 之前的方法来更改此行为。ThreadException这仅适用于主应用程序线程。UnhandledException当其他线程中抛出未处理的异常时,会引发该事件。