Playing .NET Doctor: Diagnose Application Hiccups with .NET Classes
This month's .NET Nuts & Bolts covers the different .NET Framework options for diagnosing issues within your applications. It touches on a couple of the classes available in the System.Diagnostics namespace and the functionality they provide for debugging and tracking an application's execution path.
For those who have been programming long enough, you probably recall a time prior to advanced development tools such as Visual Studio when diagnosing application issues was more complicated. It was a time when you could not step through your code, nor determine exactly where the application was in its execution. One of the techniques often used then was embedding a series of print statements within the code to display the output at any given point in time and track the application logic flow. These statements had to be removed prior to application deployment, but one or two invariably would remain and cause embarrassment when displayed. Microsoft has included the Debug and Trace classes in the. NET Framework to help with this style of debugging and to avoid some of the pitfalls.
Modern Day Debugging
The System.Diagnostics.Debug class provides a set of methods and properties for debugging code. The methods in the Debug class offer a number of very useful options. One of them is that it displays the messages only when the code is compiled as a debug build. (Note: the debug build option is compiler specific. In C#, it is /d:DEBUG. In Visual Basic .NET, it is /d:DEBUG=True. I prefer just to let Visual Studio control it for me by changing the mode through Configuration Manager.) The result is that the debug statements can remain in the code at all times and can be easily excluded from production code simply by compiling without the debug option.
System.Diagnostics.Debug Sample Code
The following are some of the more common methods available in the Debug class:
- Assert—Displays a dialog message if the condition being checked is false
- Write/WriteLine—Writes information with or without a new line
- WriteIf/WriteLineIf—Conditionally writes information with or without a new line
- Indent/Unindent—Indents or unindents the debugging output
The following sample code demonstrates all the methods listed above. The Assert statement results in a dialog box (Figure 1), while the others result in output being displayed in the Debug section of the Output window (Figure 2):
System.Diagnostics.Debug.Assert(false, "Message","Detail message to show in the debug window.");Random rand = new Random(100);System.Diagnostics.Debug.Indent();System.Diagnostics.Debug.WriteLine("First random numbeCr: " + rand.Next().ToString());System.Diagnostics.Debug.Unindent();System.Diagnostics.Debug.WriteLineIf(rand.Next()%2 == 0, "Even random number generated.");
Figure 1: Assert Output
Figure 2: Debug Output
Using a Configuration File
Another handy System.Diagnostics.Debug option is the ability to control the Debug class through the application's configuration file (web.config or app.config). A <system.diagnostics> element allows control of the behavior. The following example sets the size of indentions when printing and controls whether or not the Assert method generates a dialog:
<system.diagnostics> <trace autoflush="true" indentsize="7" /> <assert assertuienabled="false" /></system.diagnostics>
When you add the items above to your configuration file and execute it, you see slightly different output. Instead of the dialog from Figure 2, the output displays larger indention than the default (see Figure 3).
Figure 3: Control Debug Through Configuration
The System.Diagnostics.Trace class provides a set of methods and properties for tracing the execution of code. These statements are often handy when you deal with complex logic and aren't sure where the code is at in execution. Trace statements are very similar to Debug statements. Trace exposes the same methods and functionality as the Debug class offers. The difference is that Trace is enabled by default for both debug and release builds. Thus, Trace statements can be used to trace the execution of code when it has been released to production. This can be handy for finding additional information on how your application is behaving in production.