When you use structured exception handling in a Microsoft
Windows Forms application, the exception may not propagate correctly to the calling
function. This behavior may occur if you run your Windows Forms application without
using the debugger. When this behavior occurs, you may receive the following error message:
An unhandled exception has occurred in your application. If you
click continue, the application will ignore this error and attempt to continue.
If you click Quit the application will shut down immediately. My Exception
However, if you run your Windows Forms application with the debugger,
you may not receive this error message.
When you run your Windows Forms application without using
the debugger, you use the NativeWindow.CallBack method to catch the exception and to prevent the program from
unexpectedly quitting (crashing). In the NativeWindow.CallBack method, you populate the exception message by using a standard
exception dialog box.
However, if you run your Windows Forms
application with the debugger, you do not catch the exception because you use
the NativeWindow.DebuggableCallBack method. When you use the NativeWindow.DebuggableCallBack method, the just-in-time (JIT) debugger stops the application
from running.
Press CTRL+F5 to run the application without using the
debugger.
Another workaround for this behavior is to use the Application.OnThreadException handler. Add the following code to the Form1 class. This code works the same way both with debugger and
without the debugger.
[STAThread]
static void Main()
{
CustomExceptionHandler eh = new CustomExceptionHandler();
Application.ThreadException += new ThreadExceptionEventHandler(eh.OnThreadException);
Application.Run(new Form1());
}
internal class CustomExceptionHandler
{
public void OnThreadException(object sender, ThreadExceptionEventArgs t)
{
// MessageBox.Show("OnThreadException - Handling the following exception: \n \n" + t.Exception.Message);
throw t.Exception;
}
}
On the File menu, point to
New, and then click Project. The New
Project dialog box appears.
Under Project Types, click Visual
C# Projects. Under Templates, click Windows
Application projects. Click OK. By default, a form
that is named Form1 is created.
Switch to the code view.
In the Form1 form, replace the existing code with the
following code.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace WindowsApplication1
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
/// <summary>
/// Windows Form Designer requires this variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Windows Form Designer requires this method.
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call.
//
}
/// <summary>
/// Clean up any resources that are being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Windows Form Designer requires this method. Do not modify
/// the contents of this method by using the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(64, 104);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(160, 40);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
try
{
Application.Run(new Form1());
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void button1_Click(object sender, System.EventArgs e)
{
try
{
Form2 frm = new Form2();
frm.Show();
}
catch (System.Exception exc)
{
MessageBox.Show("Handling the following exception: \n \n" + exc.Message);
}
}
}
}
In Solution Explorer, right-click the project, point to
Add, and then click Add New Item. The
Add New Item dialog box appears.
Under Templates, click Windows
Form. By default, a form that is named Form2 is created.
In the Form2 form, replace the existing code with the
following code.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace WindowsApplication1
{
/// <summary>
/// Summary description for Form2.
/// </summary>
public class Form2 : System.Windows.Forms.Form
{
/// <summary>
/// Windows Form Designer requires this variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form2()
{
//
// Windows Form Designer requires this method.
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call.
//
}
/// <summary>
/// Clean up any resources that are being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Windows Form Designer requires this method. Do not modify
/// the contents of this method by using the code editor.
/// </summary>
private void InitializeComponent()
{
//
// Form2
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Name = "Form2";
this.Text = "Form2";
this.Load += new System.EventHandler(this.Form2_Load);
}
#endregion
private void Form2_Load(object sender, System.EventArgs e)
{
throw new System.Exception("My Exception");
}
}
}
On the Build menu, click Build
Solution. Then, press CTRL+F5 to run the application without using
the debugger.