This question has been brought up many times, but I'd like to ask it again because I've read some things here that didn't seem right to me (could be because one is related to the .NET CF), and I am asking for validation of a specific approach that I think is reasonable, and would appreciate any feedback you might have.
Anyhow, the situation is much like everyone elses -- I want to handle errors originating from a thread. Currently, the code I have works fine because I'm throwing exceptions from a thread, but I am using Invoke, rather than BeginInvoke.
You're probably wondering at this point, "Why would he create a thread and then call Invoke? Why not just call a function?". The issue is that I want to give the caller flexibility via a parameter that dictates whether or not the operation should be synchronous or asynchronous.
As a test, I have tested it in the asynchronous mode of operation, and as expected, it fails silently and the application dies in the debugger at the point the exception is thrown from the worker thread.
To make sure I have a basic understanding of the behavior of exceptions in threads, as well as the disprove the statement in this question on SO (at least as far as .NET 3.5 goes), I wrote some test code in a WPF app:
code removed
So it seems like there should be no problem handling events in the main thread that originate from another thread.
Provided that you agree with my tests above, my question is simply this -- is it an acceptable practice to write my method that offers both sync and async behavior where all of the business logic is wrapped in a try/catch block? Internal errors get trapped inside of the thread, and if it's a sync call, just throw the exception, and if it's an async call, just raise the event? In my sample code above, I also throw the exception after raising the event. I'm not sure if or why this would cause me any problems.
Pseudo-pseudocode:
TestFunc(async);
private TestFunc(bool async)
{
try {
throw new MyAppException("error occurred.");
} catch(MyAppException ex) {
async ? RaiseErrorEvent : throw;
}
}
UPDATE
Ok, as Hans said, it will cause issues no matter what if I throw the exception from the thread -- period. I was able to test this case out and sure enough, the exception gets thrown and if you hit F5, it just gets thrown over and over again and never terminates the thread. I don't understand this particular behavior -- is it just how it works when running through the debugger? I guess this means that I have to check if the method is getting called sync or async. If sync, throw error. If async, raise event.
Perhaps a better way to do it is to force the client to always handle errors with events, rather than catching exceptions? Anyone have thoughts on this approach?