C# – Catch Exception of a thread

During our development we must handle with a lot of errors. Working with multitasking, handling exceptions turn to be a little complex. In multi-threading the exceptions can not be cross-thread accessed, they can only be caught from the thread which code is running on.

public static void Main() 
{
	try 
	{
		new Thread (Go).Start();
	}
	catch (Exception ex) 
	{
		// We'll never get here!
		Console.WriteLine ("Exception!");
	}
}

static void Go() 
{ 
	throw null; 
}

In the code above, we never land to the code where we catch exception in main function. The try/catch statement in example above is effectively useless, and the newly created thread will be encumbered with an unhandled NullReferenceException. This behavior makes sense when you consider a thread has an independent execution path. The remedy is for thread entry methods to have their own exception handlers. So what should we do if we want to catch exception? I would like to enumerate some cases which I deal with exceptions of thread.
1. BackgroundWorker
The BackgroundWorker provides us a simple way to handle with exceptions. It’s pretty easy to catch them. If the operation raises an exception that your code does not handle, the BackgroundWorker catches the exception and passes it into the RunWorkerCompleted event handler, where it is exposed as the Error property of RunWorkerCompletedEventArgs.We just need to handle as example below

void m_bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
	if (e.Error != null)
	{
		lblException.Text = e.Error.Message;
	}
	else if (e.Cancelled)
	{
		lblMessage.Text = "Canceled";
	}
	else
	{
		lblMessage.Text = e.Result.ToString();
		btnStart.Text = "Start";
	}
}

2. Normal Thread
This solution only works in case of windows form because we must call the Control.Invoke to call back to main thread and handle exceptions at main thread. To implement this solution, we just declare a delegate and its correlative method.

public partial class frmMain : Form
{
	public delegate void CatchExceptionDelegate(Exception ex);
	public delegate void UpdateResultDelegate(double dResult);

	public frmMain()
	{
		InitializeComponent();
	}

	private void CatchException(Exception ex)
	{
		lblException.Text = "Catch exception from main thread :" + ex.Message;
	}

	private void UpdateResult(double dResult)
	{
		lblException.Text = dResult.ToString();
	}
	private void btnSqrt_Click(object sender, EventArgs e)
	{   
		Thread thCalculateSqrt = new Thread(new ParameterizedThreadStart(SqrtCalculate));
		thCalculateSqrt.Start(txtNumber.Text);         
	}

	public void SqrtCalculate(object nNumber)
	{
		try
		{
			double dArg = Convert.ToDouble(nNumber);
			double dResult = Math.Sqrt(dArg);
			Math.Sign(dResult);
			this.Invoke(new UpdateResultDelegate(this.UpdateResult), dResult);
		}
		catch (ArithmeticException ex)
		{
			this.Invoke(new CatchExceptionDelegate(this.CatchException), ex);
		}
	}
} 

As you can see, it’s pretty simple. The complete source code you can download “Catch thread exception

3. Global exceptions
From .NET 2.0 onwards, an unhandled exception on any thread shuts down the whole application, meaning ignoring the exception is generally not an option. Hence a try/catch block is required in every thread entry method – at least in production applications – in order to avoid unwanted application shutdown in case of an unhandled exception. This can be somewhat cumbersome – particularly for Windows Forms programmers, who commonly use the “global” exception handler, as follows

static void Main()
{
	Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
	Application.EnableVisualStyles();
	Application.SetCompatibleTextRenderingDefault(false);
	Application.Run(new frmMain());
}

static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
	throw new NotImplementedException();
}

The Application.ThreadException event fires when an exception is thrown from code that was ultimately called as a result of a Windows message (for example, a keyboard, mouse or “paint” message) – in short, nearly all code in a typical Windows Forms application. While this works perfectly, it lulls one into a false sense of security – that all exceptions will be caught by the central exception handler. Exceptions thrown on worker threads are a good example of exceptions not caught by Application.ThreadException (the code inside the Main method is another – including the main form’s constructor, which executes before the Windows message loop begins).
The .NET framework provides a lower-level event for global exception handling: AppDomain.UnhandledException. This event fires when there’s an unhandled exception in any thread, and in any type of application (with or without a user interface). However, while it offers a good last-resort mechanism for logging untrapped exceptions, it provides no means of preventing the application from shutting down – and no means to suppress the .NET unhandled exception dialog.

One thought on “C# – Catch Exception of a thread”

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>