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是一个解决方案,因为我不希望异常一直回到第一个对话框,然后是主应用程序.我不想关闭应用程序,我只想记录它,显示一条消息,让它们从对话框中取消.他们可以决定从那里做什么(也许去应用程序的其他地方).
基本上,第一个对话框和第二个对话框之间的"全局处理程序"(然后,我想,主应用程序和第一个对话框之间的另一个"全局处理程序").
是的,Application.ThreadException的默认处理是一个错误.不幸的是,这是一个必要的错误,不需要立即阻止和绝望成千上万的程序员编写他们的第一个Windows窗体应用程序.
你正在考虑的修复不是一个修复,它有很大的潜力,使它变得更糟.当用户单击异常对话框上的"继续"按钮是一个值得怀疑的结果时,吞噬全局异常处理程序中的异常会更糟糕.
是的,请为ThreadException编写替换处理程序.让它在消息框中显示e.Exception.ToString()的值,以便用户知道爆炸的内容.然后触发电子邮件或附加到错误日志,以便您知道出了什么问题.然后调用Environment.FailFast(),这样就不会再造成任何损害.
对AppDomain.CurrentDomain.UnhandledException执行相同操作.它不会得到很多锻炼.
使用反馈来改进您的代码.您将找到需要验证的位置.您可以帮助客户的IT人员诊断LAN和设备的故障.并且您会发现极少数情况下您自己的try/catch块可能能够从异常中恢复.
您可以使用AppDomain.CurrentDomain.UnhandledException处理程序拦截主 UI 线程上的错误并按对话框处理它们。来自 MSDN:
在使用 Windows 窗体的应用程序中,主应用程序线程中未处理的异常会导致
Application.ThreadException引发该事件。如果处理此事件,则默认行为是未处理的异常不会终止应用程序,尽管应用程序仍处于未知状态。在这种情况下,UnhandledException不会引发该事件。可以通过使用应用程序配置文件或使用将Application.SetUnhandledExceptionMode模式更改为 连接事件处理程序UnhandledExceptionMode.ThrowException之前的方法来更改此行为。ThreadException这仅适用于主应用程序线程。UnhandledException当其他线程中抛出未处理的异常时,会引发该事件。