Debug and Trace a .NET Application

Debugging and tracing are both enables you to log information about your application’s health, current status, etc. The main difference is that debugging is only allowed (it runs only) in debug mode. You can define a debug mode by adding the #define DEBUG command at the top of your code (or compiling your code with the /d:DEBUG flag.

We’ll cover the following classes and attributes in this post:

  • Debug
  • Debugger
  • Debugger Attributes
    • DebuggerBrowsable
    • DebuggerDisplay
    • DebuggerHidden
    • DebuggerNonUserCode
    • DebuggerStepThrough
    • DebuggerTypeProxy
  • Trace
  • TraceListener
    • EventLogTraceListener
    • XmlWriterTraceListener
    • DelimitedListTraceListener

Debug class helps you debug your code. Now that you know it, let’s see the methods and properties:

Most Useful Static Properties and Methods of Debug
Assert Checks for a condition, and shows a message (classic Abort/Retry/Cancel) when the condition is false.
Fail Shows an error message (and optionally a detailed one).
Indent Increases the current value of IndentLevel by one.
IndentLevel An int which specifies the current level of indentation.
IndentSize The number of spaces in one indent.
Listeners A strongly-typed TraceListenerCollection of the listeners of Debug.
Print Writes a formatted string with a line terminator to the listeners.
UnIndent Decreases the current value of the IndentLevel by one.
Write/WriteLine Writes a message, an object’s ToString and a category name (depended on the overload) to the listeners.
WriteIf/WriteLineIf The same as write. The first parameter is always a condition, and the message will be written if it is evaluated true.


Now to understand the differences between Debug and Debugger, let’s see the static methods and properties of Debugger:

Static Methods and Property of Debugger
Break Creates a breakpoint at the specified line.
IsAttached If the debugger is attached to a process.
IsLogging If logging is enabled to an attached debugger.
Launch Launches and attaches the debugger to a process.
Log(int Level, string Category, string Message) Posts a message to an attached debugger.


To finish debuggers, I’ll provide a list of the most useful debugger attributes. These attributes control the appearance of your object in a debugger (such as Visual Studio). To gain a deeper understand of them, play around with them a little. These attributes can be applied to almost everything in your code. The list:

  • DebuggerBrowsable: takes a value from the DebuggerBrowsableState enumeration, which can be: Never, Collapsed, RootHidden. This indicates how a given class, property, filed or indexer should be visible in the debugger.
  • DebuggerDisplay: this attribute takes a string which defines how the value of a given property should be shown in a debugger window. It uses placeholders, so if you have an int named Count, you could use it as: [DebuggerDisplay(“Number of items: {Count}”)]
  • DebuggerHidden: debuggers won’t stop at a method marked with this attribute, and won’t enable you to set breakpoints there.
  • DebuggerNonUserCode:  when you work with code that a designer created, you can apply this attribute to that part of the code. The debugger won’t stop there.
  • DebuggerStepThrough: the debugger won’t stop methods marked by this attribute, but allows a breakpoint to be set there.
  • DebuggerTypeProxy: I must confess that I don’t very understand this attribute, nor the usefulness of it. Read the MSDN article here.

So long for debugging. Now turn to the classes of trace. Trace is used for monitoring a running application. The methods of Trace writes tracing output to the trace listeners subscribed to it. Tracing can be enabled by providing the #define TRACE code at the top of your code file, or compiling your program with the /d:TRACE flag. However, it’s enabled by default, so you won’t have to take care.

The Trace class extends the methods of the Debug class with the following methods:

Methods of Trace
TraceError(string Format, params object[] args) Writes a formatted error message to the trace listeners.
TraceInformation Writes info to listeners.
TraceWarning Writes warning to listeners.


To listen to events of the trace, you should use a TraceListener derived class, for example EventLogTraceListener. Each TraceListener defines a place to write to. EventLogTraceListener has an EventLog property, which takes an EventLog instance. XmlWriterTraceListener and DelimitedTraceListener have a Writer property, which is a TextWriter, DefaultTraceListener has nothing.

Now listen carefully, because all of this so far isn’t worth a damn thing for the exam, thanks to the TraceSource and TraceSwitch classes. They become the valid successors of the static methods of Debug and Trace.

You should set up the connections between TraceSources and TraceSwitches by using config files.

A simplified configuration file:

    <source name=”TraceSourceApp” switchName=”TraceSwitch” switchType=”System.Diagnostics.SourceSwitch”>
      <add name=”console” type=”System.Diagnostics.ConsoleTraceListener”/>
    <add name=”TraceSwitch” value=”Warning”/>

Further Readings

Use TraceSource and TraceSwitches


Tags: , ,

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: