Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Yes, this is by design and is closely associated with the way Windows Forms works. In a Winforms app, code runs in response to messages posted to the active window by Windows. Every native Windows app contains a message loop to detect these messages. The Winforms plumbing ensures one of your event handlers runs in response; button1_Click in your example code.</p> <p>Most Winforms controls implement their own event handlers. A PictureBox for example has a Paint event handler that ensures its Image is drawn to the screen. This is all done automatically, you don't have to write any code yourself to make this work.</p> <p>There is however a problem when this code throws an exception, there is no way for you to catch such an exception since none of your own code was involved. In other words, there is no place for you to inject your own try block. The very last bit of your own program's code that was involved is the code that got the message loop started. The Application.Run() method call, normally in Program.cs. Or the Form.ShowDialog() call if you display a dialog. Either of those methods start a message loop. Putting a try block around the Application.Run() call isn't useful, the app will terminate after catching an exception.</p> <p>To combat this problem, the Winforms message loop code contains a try block around the code that dispatches an event. Its catch clause displays the dialog you mentioned, it is implemented by the ThreadExceptionDialog class.</p> <p>Getting to the point of your question: this catch clause really gets in the way of troubleshooting problems with your code when you debug. The debugger will only stop on an exception when there is no catch block that handles the exception. But when your code throws an exception, you'll want to know about it when you debug. The previously mentioned code in the message loop is aware whether or not a debugger is attached. If it is, it dispatches events without the try/catch block. Now, when your code throws an exception, there is no catch clause to handle it and the debugger will stop the program, giving you a chance to find out what went wrong.</p> <p>Perhaps you see now why your program behaves the way it does. When you debug, the catch clause in the message loop is disabled, giving the catch clause in the Form1 code a chance to catch the exception. When you don't, the message loop catch clause handles the exception (by displaying the dialog) and prevents the exception from unwinding to the Form1 code.</p> <p>You can prevent the message loop catch clause from being used at all by calling the Application.SetUnhandledExceptionMode() method, passing UnhandledExceptionMode.ThrowException. Do so in the Main() method, before the Application.Run() call. Now your program will behave the same either way.</p> <p>This is in general not a bad idea, giving the user the option to Continue in the exception dialog is a questionable feature. Do implement an event handler for AppDomain.UnhandledException event in that case so there's at least some diagnostic to the user.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload