Today I was playing with exception handling and threading in .NET. It was really fun.

Do you know guys that like to have everything in global try-catch block? I have two news for them.

Bad one

Exception will not be caught in try-catch block if it was thrown in another thread. Those guys also could think that Application.ThreadException could help them to catch those.

        [STAThread]
        static
void
Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.ThreadException += Application_ThreadException;
         
            Application.Run(new Form1());
        }

        static
void
Application_ThreadException(object
sender, System.Threading.ThreadExceptionEventArgs
e)
        {
            MessageBox.Show(“This is
something that I would not recommend you to have in your application.”
);
        }

But indeed this event fires only if exception has been thrown as result of Windows message or any other code that runs in same thread were your WinForms application lives. I tried to use two timers to verify that.
System.Windows.Forms.Timer – which ensures that code you have in your tick method runs in the same thread as your application. In this case I got message box.
System.Threading.Timer – which runs in separate thread, so my app just crashed.

But if those guys are writing all code in Form1.cs file… then maybe it worth for them to have handling of Application.ThreadException event :)

“Good” one

There is event which will be fired when exception is thrown from any code/thread withing your application domain. It is AppDomain.UnhandledException and it occurs when exception is not caught.

Lets take a look on code snippet that shows this:

        [STAThread]
        static
void
Main()
        {
            AppDomain currentDomain =
AppDomain.CurrentDomain;
            currentDomain.UnhandledException +=
currentDomain_UnhandledException;

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
         
            Application.Run(new Form1());
        }

        static
void
currentDomain_UnhandledException(object
sender, UnhandledExceptionEventArgs e)
        {
            MessageBox.Show(“This is
shown when ANY thread is thrown in ANY point of your Domain.”
);
        }

To test this I created Threading.Timer and fired it every 2 seconds and throwing exception on each tick, I put breakpoint into event. I got everything expected and application after that failed.

But one of our smart guys could guess to put Thread.Sleep(1000000); into handler code like below:

        static void currentDomain_UnhandledException(object sender,
UnhandledExceptionEventArgs e)
        {
            Thread.Sleep(1000000); //
Try to guess what will happen

        }

Everyone is happy. Exception is thrown each 2 seconds or less and UI continue to respond. I hope you already see what is wrong with all of this.

This screenshot talks for itself:

 (My app already ate 705 threads and still eats…)

And as you know process could have up to 1024 threads. My process is not exclusion and it also crashed after reached that number.

Ok, looks like guys should change their mind.

Hope it was a bit fun.