Introduction
Today I faced a strange issue; I was catching an Exception in a BackgroundWorker’s thread, threw a new exception and handled it in the main GUI thread by showing the exception’s Message in a message box.
The strange thing was, that no matter what I did, the main GUI thread always displayed the message of the first generated exception in the background thread.
Cause
As described by user „nobugz“ in this discussion, the cause is:
This is an architectural limitation to the way exceptions are marshalled from one thread (the BGW’s) to another (the UI thread). Only a single exception object can get copied, the designers chose the first one thrown as the most likely to be relevant. You’ll need to work around this restriction.
Interestingly enough this behavior seems to occur only in an Application.ThreadException handler which seems to pick up the exception from somewhere (maybe TLS?)
Resolution
The resolution is to handle the exception directly in the RunWorkerCompleted handler where it gets forwarded to and not to throw the exception any further, until the Application.ThreadException handler of the GUI thread handles it.
Example application
To show the error in a small example project I created a tiny Windows Forms application which you may download from here.
Main Window with erroneous Behavior
When the check box is activated, the erroneous behavior is being performed when clicking the button:
The first generated exception is being displayed to the end user instead the actual one that is being thrown later in the background thread.
Main Window with expected Behavior
When the check box is not activated when clicking the button, the expected result is being displayed; the latest thrown exception:
Summary
I’ve just shown you a case where (in my eyes) the .NET Framework behaves wrong.
Maybe you find this article useful or even prove that I am wrong or how to handle in a more elegant way.
Looking forward for your feedback!
Ich hab’s ja schon immer gesagt: .NET ist Teufelszeug.
Hehe, .NET-Postings sind für den Sven das Pendant zu dem hier.