I\'m seeing some wierd behaviour when throwing exceptions and catching them in the Application.ThreadException
event handler.
Basically whats happening
The RunWorkerCompleted event is marshaled from the BGW thread to the UI thread by the WF plumbing that makes Control.Invoke() work. Essentially, there's a queue with delegates that is emptied by the message loop. The code that does this, Control.InvokeMarshaledCallbacks(), you'll see it on the call stack, has a catch (Exception) clause to catch unhandled exceptions. That clause calls Application.OnThreadException, passing the value of Exception.GetBaseException().
Well, that explains why you only see the inner exception. Why it is done this way is a bit unclear. Possibly to slice off the stack frames of the code in the UI thread that are otherwise pretty confusing since the real exception came from the background thread.
if (e.Error != null)
{
throw new Exception("worker_RunWorkerCompleted", new Exception("Inner", new Exception("Inner inner")));
}
You get "inner inner" at the end. It seems that this is the behavior of Application_ThreadException method to look at the inner-most exception.