c#winform textbox验证未处理的异常

时间:2017-10-19 09:08:58

标签: c# .net forms winforms

我在活动中遇到问题" textbox验证"。 触发时,如果我抛出异常,则不会返回try catch块。

try
{
   new form().showdialog();
}
catch(exception e)
{
   console.writeline("ok");
}

然后这就留在这里,不要进入捕获:

private void TB_Validating(object sender, CancelEventArgs e)
{
   throw new Exception("aaa");
}

而是在catch代码上打印错误

private void TB_Click(object sender, CancelEventArgs e)
{
   throw new Exception("aaa");
}

有人能告诉我原因及其解决方案吗?

2 个答案:

答案 0 :(得分:4)

"为什么"是一个很长的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以强制他输入有效数据。

答案 1 :(得分:0)

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

您可以在此处理异常:

  Application.ThreadException += ... 

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