Control.Invoke rethrows any exception which occurs during the invoked operation on the original thread which called Invoke. However, the stack trace of the original is lost in the process. Instead of simply rethrowing the exception, Control.Invoke should wrap the thrown exception in a new exception to preserve the original stack trace. It should be up to the calling method to determine which is more important: the original stack trace of the exception, or rethrowing the original exception type.
Control.Invoke also strips off any outer exceptions by calling GetBaseException in the InvokeMarshaledCallbacks method. These outer exceptions often contain important information about the context in which the underlying exception occurred, and should not simply be stripped off. Again, it should be up to the caller to determine how to deal with the thrown exception; Control.Invoke should not make unfounded assumptions.
These problems are preventing us from getting critical debugging information from our applications in production. BeginInvoke/EndInvoke do not suffer from the same problems, however we do not have the option of switching; we are using the SynchronizationContext class in a library which is not WinForms-specific, and the WindowsFormsSynchronizationContext is hard coded to use Control.Invoke. I am not aware of any workarounds that are not WinForms-specific, which is unacceptable. Our apps are simply failing and we have no way of finding out why.