rocessing exceptions in any language is expensive. The process of capturing an exception and rolling it into a package that can be processed by code requires a stack walkbasically looking back through the history of what has happenedand that requires a lot of processing time to complete. In .NET software development we sometimes talk about boxing and unboxing of variables and how that can consume a great deal of time in a programand it can. However, the amount of time necessary to process an exception dwarfs the time necessary to box and unbox a variable. (If you want to know more about boxing and unboxing you can read about it in the article "Boxing and Unboxing of Value Types in C#
" on CodeGuru.)
Despite the fact that exceptions are expensive to process they are positively a great thing for debugging applications and making software more reliable. The challenge is when exceptions are used incorrectly; specifically, when they are used to respond to normal conditions instead of exceptional conditions. Generally when this happens the layers of software above the layer generating the exception start "eating" the exceptionbecause nothing is wrong (more on eating exceptions in a moment)and manually return to normal program flow. This, however, leads to subtle performance issues that are difficult to find. Running a profiler on the code can show where performance is being impacted, however, there's a quicker and simpler way to find performance problems like theseor rule out exceptions as a potential cause of performance issues.
Using first chance exceptions in the debugger is a way to ferret out these hidden exceptions that your application is generating so that you can go back and prevent them from happening in the first place. The more exceptions you prevent, the faster your application will run. First chance exceptions are exposed via Visual Studio and can be leveraged in any language that compiles to the CLR.
The starting point for learning how to leverage first chance exceptions is to expose a situation where hidden exceptions are causing a performance problem.
Eating an exceptionthat is, not doing anything special when an exception is raisedis easy to do. This is the most general case of a hidden exception. The code around the code generating the exception simply doesn't do anything with it. It ignores the exception by working around the inherent problem. Although other types of hidden exceptions exist, they are really just complicated forms of the following basic pattern. A quick try/catch block can eat any exception, as shown in the code below:
sum += dblArray[dim1Loop, dim2Loop];
catch (Exception e)
The code has a try catch block but does nothing with itexcept in this case to terminate the inner loop. This loop runs substantially slower because of the exception, out of bounds, that is thrown each time the code is ready to exit.
Anytime there is a catch without any code inside the catch block, the application has eaten the exception. Even if there is code inside the catch block it doesn't necessarily mean that the code isn't eating the exception. In the above case, the trace statement is commented out, but even if that weren't the case, the code would still eat the exception because the trace statement doesn't log or resolve the original reason for the exception.
Now that you can recognize a pattern for an eaten (and therefore potentially unnecessary) exception, let's turn on first chance exceptions in the debugger and see where these are in your application.