我对事件“文本框验证”有疑问。 触发时,如果我抛出异常,这不会返回到 try catch block 。
try
{
new form().showdialog();
}
catch(exception e)
{
console.writeline("ok");
}
然后就呆在这里,不要陷入困境:
private void TB_Validating(object sender, CancelEventArgs e)
{
throw new Exception("aaa");
}
相反,这会在捕获代码上打印错误
private void TB_Click(object sender, CancelEventArgs e)
{
throw new Exception("aaa");
}
谁能告诉我原因和解决方法?
最佳答案
“为什么”很长而且painful story这不太适合 SO 答案。黄金法则是异常绝不能导致调度程序循环终止。您可以通过调用 Application.Run()(如在 Main() 入口点中所做的那样)或调用 Form.ShowDialog()(如在此代码段中所做的那样)来使调度程序循环循环。正是该循环确保 ShowDialog() 在您关闭对话框之前不会返回。
Winforms 通过在调度程序循环中使用 try/catch-em-all 语句来遵守该规则。如果事件处理程序抛出异常,它会引发 Application.ThreadException 事件。如果您不替换或禁用事件处理程序(您应该这样做),那么您将看到 ThreadExceptionDialog,它允许用户选择“继续”或明智地单击“退出”。
然而,当您调试时,那个 catch-em-all 处理程序非常不方便。它会妨碍诊断未处理的异常。因此 Winforms 检查您是否调试,如果您调试,将不使用 try/catch-em-all 并且不引发 ThreadException 事件。这对代码段中的代码有很大的副作用,现在 catch 语句确实似乎工作得很好。但是一旦你按照用户的方式运行你的程序,没有调试器,它就永远不会捕获任何东西。
所以冷酷的事实是,在事件处理程序中抛出异常是错误的做法。除了不稳定的 ThreadExceptionDialog 之外,周围没有人可以捕捉到它。您必须做异常处理程序会做的事情,而不是抛出。对于应该是 ErrorProvider 的 Validating 事件,给用户一个温和的提示,提示他的数据输入不正确。或者设置e.Cancel = true强制他输入有效数据。
关于c# winform textbox 验证未处理的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46826389/