Do you remember the good ol' days before the ApplicationException class in the .NET Framework became "persona non grata"? I sure do.
If you were to look at .NET code that I wrote years ago, you'd probably see ApplicationException being used all over the place. After all, this seemed like a great way to differentiate between "expected" errors in your code (e.g. a violation of some business rule) vs. truly "unexpected" errors (e.g. an invalid parameter passed to a method).
Since we didn't expect instances of ApplicationException to be thrown by the .NET Framework itself, it seemed like a good idea to use ApplicationException as a way to determine which errors should be caught and shown to end users (i.e. "handled gracefully") vs. errors for which there's rarely any point in catching. For example, what is a user really going to do when you tell them "Object reference not set to an instance of an object?" Besides, of course, to curse your application under their breath or, even worse, openly vent their frustration to everyone within shouting distance.
Since we shouldn't be using ApplicationException anymore, we need some other way of distinguishing different types of errors. Personally, I recommend throwing a custom RecoverableException (or an exception that derives from RecoverableException) in scenarios where the user -- or an administrator -- can take some action in order to resolve the error. In other words, somebody -- besides a developer -- should be able to understand what the error means and consequently do something in order to recover from the error. Note that the "something" might simply be a matter of waiting a short period and trying the operation again (for example, when a remote Web service returns a "server too busy" error).
Read more: Random Musings of Jeremy Jameson