繁体   English   中英

c#winform文本框验证未处理的异常

[英]c# winform textbox Validating unhandled exception

我对“文本框验证”事件有疑问。 当被触发时,如果抛出异常,则不会返回到try catch块。

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");
}

谁能建议我原因和解决方案?

“为什么”是一个漫长而痛苦的故事 ,无法很好地满足SO的答案。 黄金法则是,异常绝不能导致调度程序循环终止。 您可以通过调用Application.Run()来使调度程序循环进行循环,如在Main()入口点中所做的那样,或通过Form.ShowDialog()像本代码片段中那样进行。 正是这种循环确保了ShowDialog()在关闭对话框之前不会返回。

Winforms通过在调度程序循环中使用try / catch-em-all语句来遵守该规则。 如果事件处理程序引发异常,它将引发Application.ThreadException事件。 如果您不替换(或禁用)事件处理程序(应该这样做),那么您将看到ThreadExceptionDialog,它使用户可以在“ Continue”上进行赌博或明智地单击“ Quit”。

但是,在调试时,这种万能的处理程序非常不方便。 它妨碍了诊断未处理的异常。 因此,Winforms会检查是否进行调试以及是否进行调试,否则将使用try / catch-em-all并不会引发ThreadException事件。 这对您代码段中的代码有很大的副作用,现在catch语句似乎确实可以正常工作。 但是,只要您按照用户的方式运行程序,而无需调试器,它就不会捕获任何东西。

所以冷酷的事实是,在事件处理程序中引发异常只是错误的事情。 除了笨拙的ThreadExceptionDialog之外,没有其他人可以抓住它。 而不是抛出,您必须执行异常处理程序将执行的操作。 对于应该为ErrorProvider的Validating事件,给用户一个温和的提示,即他的数据输入不正确。 或将e.Cancel = true设置为强制他输入有效数据。

在窗体的ShowDialog方法内部未调用事件处理程序TextBoxValidating 而是从GUI线程消息泵中调用它(您可以在https://en.wikipedia.org/wiki/Message_loop_in_Microsoft_Windows中找到Windows消息泵的基本描述)。 这就是为什么您无法在代码中捕获它的原因(因为您的代码未调用该方法)。

您可以在此处处理异常:

  Application.ThreadException += ... 

我不知道为什么从ShowDialog消息思想内部调用Button Click处理程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM