Let's say you have the delegate:
delegate void Foo(string x);
And a method that does some job and then it might crash. (here crashes always).
void Method(string txt)
//do code here;
throw new Exception("Unhandled exception never caught unless a debugger attached");
And another method that starts the first one asynchronous on a thread pool thread.
The most common mistake made by programmer lazyness is passing null,null as parameters on BeginInvoke.
This brings strange scenarios into your multithreaded application by never discovering some exceptions; the thread will be aborted and you will never be noticed inside your app unless you do some advanced coding or simply use the asynch pattern.
The usual pattern would be to add the method:
void CallBackMethod(IAsynchResult aRes)
if(aRes==null OR aRes.AsynchState==null)
Foo deleg=aRes.AsynchState as Foo;
and replace BeginInvoke("text", null, null) with BeginInvoke("text", CallBackMethod, foo);
This means that in case an unhandled exception happened on the sepparate thread, you will trap the error on EndInvoke - either put a catch or let it propagate.
I encourage to avoid catching errors in multithreaded apps, let the error propagate, crash the application, analyze the crash and improve your code, rather than catching errors and have a bad performance on your app.
A few usefull links(some oldie but good):