C# – Globally catch exceptions in a WPF application


We are having a WPF application where parts of it may throw exceptions at runtime. I'd like to globally catch any unhandled exception and log them, but otherwise continue program execution as if nothing happened (kinda like VB's On Error Resume Next).

Is this possible in C#? And if so, where exactly would I need to put the exception handling code?

Currently I can't see any single point where I could wrap a try/catch around and which would catch all exceptions that could occur. And even then I would have left whatever has been executed because of the catch. Or am I thinking in horribly wrong directions here?

ETA: Because many people below pointed it out: The application is not for controlling nuclear power plants. If it crashes it's not that much a big deal but random exceptions that are mostly UI-related are a nuisance in the context where it would be used. There were (and probably still are) a few of those and since it uses a plugin architecture and may be extended by others (also students in that case; so no experienced developers that are able to write completely error-free code).

As for the exceptions that get caught: I do log them to a log file, including the complete stack trace. That was the whole point of that exercise. Just to counter those people that were taking my analogy to VB's OERN too literally.

I know that blindly ignoring certain classes of errors is dangerous and might corrupt my application instance. As said before, this program isn't mission-critical for anyone. No-one in their right mind would bet the survival of the human civilization on it. It's simply a little tool for testing certain design approaches wrt. software engineering.

For the immediate use of the application there are not many things that can happen on an exception:

  • No exception handling – error dialog and application exit. Experiment has to be repeated, though likely with another subject. No errors have been logged, which is unfortunate.
  • Generic exception handling – benign error trapped, no harm done. This should be the common case judged from all errors we were seeing during development. Ignoring this kind of errors should have no immediate consequences; the core data structures are tested well enough that they will easily survive this.
  • Generic exception handling – serious error trapped, possibly crash at a later point. This may happen rarely. We've never seen it so far. The error is logged anyway and a crash might be inevitable. So this is conceptually similar to the very first case. Except that we have a stack trace. And in the majority of cases the user won't even notice.

As for the experiment data generated by the program: A serious error would at worst just cause no data to be recorded. Subtle changes that change the result of the experiment ever so slightly are pretty unlikely. And even in that case, if the results seem dubious the error was logged; one can still throw away that data point if it's a total outlier.

To summarize: Yes, I consider myself still at least partially sane and I don't consider a global exception handling routine which leaves the program running to be necessarily totally evil. As said twice before, such a decision might be valid, depending on the application. In this case it was judged a valid decision and not total and utter bullshit. For any other application that decision might look different. But please don't accuse me or the other people who worked on that project to potentially blow up the world just because we're ignoring errors.

Side note: There is exactly one user for that application. It's not something like Windows or Office that gets used by millions where the cost of having exceptions bubble to the user at all would be very different in the first place already.

Best Solution

Use the Application.DispatcherUnhandledException Event. See this question for a summary (see Drew Noakes' answer).

Be aware that there'll be still exceptions which preclude a successful resuming of your application, like after a stack overflow, exhausted memory, or lost network connectivity while you're trying to save to the database.