P
paul.mason
I was wondering if anyone else had come across this "feature" of .NET
and if they had any idea what might be causing it.
I've been writing my first C# Windows application (so if there's
anything so appalling in my code that it gives experienced developers a
touch of the vapours, I hope you'll be indulgent!) I've written my own
code to handle unexpected exceptions and I've added this as the handler
to Application.ThreadException. It all works fine - until my WinForm
has a radiobutton on it with its Checked property set to True at design
time, at which point the handler is no longer called. Switch the
checked property back to false, or set it to True at runtime, and
everything is fine again, and the custom handler captures the exception
and allows the application to exit gracefully.
I suspect this is a feature of the .NET framework rather than C# in
particular, which is why I've posted here. I've not been able to find
this mentioned anywhere else online, despite quite a few searches.
The following code will replicate the problem:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace Steria.ExceptionManagementTemplate
{
/// <summary>
/// Summary description for Test.
/// </summary>
public class Test : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private System.Windows.Forms.GroupBox fraErrorType;
private System.Windows.Forms.RadioButton optDatabaseUnavailable;
private System.Windows.Forms.RadioButton optUnexpectedException;
public static Test AppForm;
public Test()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources 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>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.fraErrorType = new System.Windows.Forms.GroupBox();
this.optUnexpectedException = new
System.Windows.Forms.RadioButton();
this.optDatabaseUnavailable = new
System.Windows.Forms.RadioButton();
this.fraErrorType.SuspendLayout();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(160, 112);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(104, 24);
this.button1.TabIndex = 1;
this.button1.Text = "Test";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// fraErrorType
//
this.fraErrorType.Controls.Add(this.optUnexpectedException);
this.fraErrorType.Controls.Add(this.optDatabaseUnavailable);
this.fraErrorType.Location = new System.Drawing.Point(8, 16);
this.fraErrorType.Name = "fraErrorType";
this.fraErrorType.Size = new System.Drawing.Size(256, 88);
this.fraErrorType.TabIndex = 17;
this.fraErrorType.TabStop = false;
//
// optUnexpectedException
//
this.optUnexpectedException.Location = new System.Drawing.Point(16,
24);
this.optUnexpectedException.Name = "optUnexpectedException";
this.optUnexpectedException.Size = new System.Drawing.Size(232, 16);
this.optUnexpectedException.TabIndex = 8;
this.optUnexpectedException.Text = "Unexpected Exception";
//
// optDatabaseUnavailable
//
this.optDatabaseUnavailable.Location = new System.Drawing.Point(16,
48);
this.optDatabaseUnavailable.Name = "optDatabaseUnavailable";
this.optDatabaseUnavailable.Size = new System.Drawing.Size(232, 16);
this.optDatabaseUnavailable.TabIndex = 7;
this.optDatabaseUnavailable.Text = "Database Unavailable";
//
// Test
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(280, 141);
this.Controls.Add(this.fraErrorType);
this.Controls.Add(this.button1);
this.Name = "Test";
this.Text = "Test";
this.fraErrorType.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
AppForm = new Test();
Application.ThreadException += new
System.Threading.ThreadExceptionEventHandler(AppForm.GlobalExceptionHandler);
Application.Run(AppForm);
}
private void button1_Click(object sender, System.EventArgs e)
{
DivideByZeroException ex = new DivideByZeroException();
throw ex;
}
public void GlobalExceptionHandler (object source,
System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show ("GlobalExceptionHandler", "The
GlobalExceptionHandler has been called.");
}
}
}
and if they had any idea what might be causing it.
I've been writing my first C# Windows application (so if there's
anything so appalling in my code that it gives experienced developers a
touch of the vapours, I hope you'll be indulgent!) I've written my own
code to handle unexpected exceptions and I've added this as the handler
to Application.ThreadException. It all works fine - until my WinForm
has a radiobutton on it with its Checked property set to True at design
time, at which point the handler is no longer called. Switch the
checked property back to false, or set it to True at runtime, and
everything is fine again, and the custom handler captures the exception
and allows the application to exit gracefully.
I suspect this is a feature of the .NET framework rather than C# in
particular, which is why I've posted here. I've not been able to find
this mentioned anywhere else online, despite quite a few searches.
The following code will replicate the problem:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace Steria.ExceptionManagementTemplate
{
/// <summary>
/// Summary description for Test.
/// </summary>
public class Test : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private System.Windows.Forms.GroupBox fraErrorType;
private System.Windows.Forms.RadioButton optDatabaseUnavailable;
private System.Windows.Forms.RadioButton optUnexpectedException;
public static Test AppForm;
public Test()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources 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>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.fraErrorType = new System.Windows.Forms.GroupBox();
this.optUnexpectedException = new
System.Windows.Forms.RadioButton();
this.optDatabaseUnavailable = new
System.Windows.Forms.RadioButton();
this.fraErrorType.SuspendLayout();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(160, 112);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(104, 24);
this.button1.TabIndex = 1;
this.button1.Text = "Test";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// fraErrorType
//
this.fraErrorType.Controls.Add(this.optUnexpectedException);
this.fraErrorType.Controls.Add(this.optDatabaseUnavailable);
this.fraErrorType.Location = new System.Drawing.Point(8, 16);
this.fraErrorType.Name = "fraErrorType";
this.fraErrorType.Size = new System.Drawing.Size(256, 88);
this.fraErrorType.TabIndex = 17;
this.fraErrorType.TabStop = false;
//
// optUnexpectedException
//
this.optUnexpectedException.Location = new System.Drawing.Point(16,
24);
this.optUnexpectedException.Name = "optUnexpectedException";
this.optUnexpectedException.Size = new System.Drawing.Size(232, 16);
this.optUnexpectedException.TabIndex = 8;
this.optUnexpectedException.Text = "Unexpected Exception";
//
// optDatabaseUnavailable
//
this.optDatabaseUnavailable.Location = new System.Drawing.Point(16,
48);
this.optDatabaseUnavailable.Name = "optDatabaseUnavailable";
this.optDatabaseUnavailable.Size = new System.Drawing.Size(232, 16);
this.optDatabaseUnavailable.TabIndex = 7;
this.optDatabaseUnavailable.Text = "Database Unavailable";
//
// Test
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(280, 141);
this.Controls.Add(this.fraErrorType);
this.Controls.Add(this.button1);
this.Name = "Test";
this.Text = "Test";
this.fraErrorType.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
AppForm = new Test();
Application.ThreadException += new
System.Threading.ThreadExceptionEventHandler(AppForm.GlobalExceptionHandler);
Application.Run(AppForm);
}
private void button1_Click(object sender, System.EventArgs e)
{
DivideByZeroException ex = new DivideByZeroException();
throw ex;
}
public void GlobalExceptionHandler (object source,
System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show ("GlobalExceptionHandler", "The
GlobalExceptionHandler has been called.");
}
}
}