I have an idea why but I'd like to ask if someone has a good grasp on why the exception raised inside a thread is never caught by the code that started it. Here's some very simple code to demonstrate what I mean:
using System;
using System.Collections.Generic;
using System.Threading;
namespace TestCrash
{
class Program
{
private static void Crash(object control)
{
AutoResetEvent are = (AutoResetEvent)(((object[])control)[0]);
are.Set();
throw new Exception("Burn baby burn");
}
static void Main(string[] args)
{
try
{
List<WaitHandle> waitHandles = new List<WaitHandle>();
for (int i = 0; i < 100; i++)
{
AutoResetEvent are = new AutoResetEvent(false);
waitHandles.Add(are);
object[] procControl = new object[] { are };
ThreadPool.QueueUserWorkItem(Crash, procControl);
WaitHandle.WaitAll(waitHandles.ToArray());
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
I naively thought that by having the try/catch I would be safe, but I found out the hard way that it is not the case (it is crashing one of my services).
Well in general, you've no idea where the originating thread will be by the time the exception is thrown in the new thread - why would it be waiting around for the thread to throw an exception?
Think of the stacks involved - when an exception is thrown, it goes up the stack until it reaches an appropriate catch block. The new thread has a completely separate stack to the creating thread, so it'll never reach the catch block in the creating thread's stack.
EDIT: Of course, you could design your system so that the creating thread did wait for other things to happen - a bit like the message loop in a Windows Forms application. The new thread could then catch the exception and send a message to the creating thread, which could then deal with the exception. That isn't the normal setup though - you have to do it all explicitly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With