views:

286

answers:

6

Is it legal and safe in C# to catch an exception on one thread, and then re-throw it on another.

E.g. is this legal

Exception localEx = null;

Thread mythread = new Thread() { () =>
                   {
                        try
                        {
                            DoSomeStuff();
                        }
                        catch(Exception ex)
                        {
                            localEx = ex;
                        }
                    });

myThread.Start();
...
myThread.Join();

if(localEx != null)
   throw localEx;    // rethrow on the main thread

I think it is legal, but I'm having trouble finding any doco that proves it. The closest I found was a brief mention of transferring exceptions between threads here: http://msdn.microsoft.com/en-us/library/ms229005.aspx

+7  A: 

Yes, it's legal. Exceptions are (generally speaking) descriptive objects with no thread affinity.

You'd be better off wrapping your thread exception in a new exception:

throw new Exception("Something descriptive here", localEx);

That way, the stack trace in localEx will be preserved (as the InnerException of the new exception).

Ben M
-1: Are you planning to add a citation? If so, I'll upvote then.
John Saunders
Your answer was "yes, it's legal". I think more is required than that. You've expanded your answer to the point where the downvote is not necessary.
John Saunders
Thanks for pointing that out. I'll do it.
John Rusk
+2  A: 

I don't see why it wouldn't work, but you need to remember that you aren't actually rethrowing the exception. You are throwing a new exception, that just happens to be the same exception object. So, for example, the stack trace will say it was thrown from "throw localEx;" instead of wherever the original exception came from.

Tal Pressman
Thanks. Yes, rethrow was the wrong word. I'll use localEx as inner exception to avoid the call stack problem you mention.
John Rusk
+2  A: 

What you're doing is not a rethrow. It's a new throw of an exception instance you happened to have in a variable. Even if you were using only a single thread, this would be a bad idea, as it makes the exception look like it came from the "throw" site. With multiple threads, I have no idea how anyone would figure out there had been a thread change.

John Saunders
+2  A: 

It is legal and it isn't a rethrow, it's a new exception being thrown on another thread (with the same exception object)

Seth Illgard
A: 

Absolutely. System.AggregateException is added to .NET 4 for specifically that purpose during parallel operations.

280Z28
A: 

I don't know why you think its not legal. If it were illegal surely the compiler would catch or the runtime would throw an exception. As a matter of fact I use this pattern. @John In a windows forms app that calls web services using a background thread I use this way. The exception is then handled in the Application.ThreadException top level handler, logged etc. It is unnecessary to know in which thread the exception occured.

Pratik