1

I have a problem on the event "textbox Validating". when fired, if I throw an exception, this doesn't return to the try catch block.

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

then this stay here and don't go in catch:

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

instead this prints the error on catch code

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

Can anyone suggest me the reason and its solution ?

Rish
  • 1,303
  • 9
  • 22
elle0087
  • 840
  • 9
  • 23
  • There isnt enough here to be sure but Id guess because form().showdialog() was successful - its something n the form thats not working... – BugFinder Oct 19 '17 at 09:15
  • 2
    It's not caught by the catch since there is no direct stack chain between the call to `ShowDialog` and the execution of the textbox event handler. – Zohar Peled Oct 19 '17 at 09:17
  • you should also show the code inside form – Min Hong Tan Oct 19 '17 at 09:19
  • 1
    hi all, thank you for support. the problem is only on Validating events, visual studio show me "unhandle exception....". instead if i run the same code in a different evento on the same form and component on exception it return to catch block...i can t understand why... – elle0087 Oct 19 '17 at 09:23

2 Answers2

4

The "why" is a long and painful story that doesn't fit that well in an SO answer. Golden rule is that an exception must never cause the dispatcher loop to terminate. You get the dispatcher loop to loop by calling Application.Run(), as is done in your Main() entrypoint, or Form.ShowDialog() as is done in this snippet. It is that loop that ensures that ShowDialog() does not return until you close the dialog.

Winforms observes that rule by having a try/catch-em-all statement in the dispatcher loop. It raises the Application.ThreadException event if an event handler throws an exception. If you don't replace or disable the event handler (you should) then you get to see the ThreadExceptionDialog, the one that lets the user gamble at "Continue" or wisely click "Quit".

That catch-em-all handler is however very inconvenient when you debug. It gets in the way of diagnosing unhandled exceptions. So Winforms checks if you debug and if you do will not use the try/catch-em-all and not raise the ThreadException event. That has a big side-effect on the code in your snippet, now that catch statement does seem to work just fine. But as soon as you run your program the way your user will do, without a debugger, then it never catches anything.

So the cold hard fact is that throwing an exception in an event handler is just the wrong thing to do. There isn't anybody around to catch it, other than the wonky ThreadExceptionDialog. Instead of throwing, you must do what an exception handler would do. For a Validating event that ought to be ErrorProvider, giving the user a gentle hint that his data entry is not correct. Or setting e.Cancel = true to force him to enter valid data.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
0

The event handler TextBoxValidating is not called inside the ShowDialog Method of the Form. Instead it is called from the GUI Thread Message Pump (You can find a basic description of the Windows message pump here https://en.wikipedia.org/wiki/Message_loop_in_Microsoft_Windows). Which is why you can not catch it in your code (because your code does not call the method).

You can handle the exception here:

  Application.ThreadException += ... 

I do not know why the Button Click handler is called from inside the ShowDialog message thought.

quadroid
  • 8,444
  • 6
  • 49
  • 82