Posted by: Cirilo Meggiolaro | 12/5/2008

Tip of the day #52 – An introduction for .NET debugging

How many times did you have to debug a code? This question really brings me a lot of memories (and applications) to my mind.

It depends on the kind of problem you want to analyze. Review code, run the code step by step, line by line, add breakpoints, save data to log files, add JavaScript alerts, generate and analyze dumps are some tasks you are going to perform.

Does it sound familiar for you?

Today’s tip explores some .NET and Visual Studio features that make your debugging process easier. The classes described here are available under the System.Diagnostics namespace.

Debbuger Class

The debbuger class provides access to communicate with the debugger application.

The following main static methods are available:

  • Break method: The break method has a function similar to a breakpoint and you can use it in conditional checks.

Debugger.Break();

  • IsAttached property: It returns a Boolean value indicating if the debugger is attached to the process;

bool Debugger.IsAttached;

  • IsLogging method: It returns a Boolean value indicating if a log is enabled;

bool Debugger.IsLogging();

  • Launch method: The method launches a debugger and attach it to the process;

bool Debugger.Launch();

  • Log method: The log method provides the functionality to send a message to a log. It works only if a listener has been created to receive log messages. We are going to check the listeners in this article.

Debugger.Log(int, string, string);

Debug Class

The debug class provides more flexibility and functionality than the Debugger class like conditional methods and more overloads to write a message to a log. The name says it all. The Debug class runs only in debug mode. The following methods are available:

  • Assert: The Assert method expects a Boolean condition as a parameter and if the condition is not evaluated properly a message is displayed;

Overloads:

Debug.Assert(bool);
Debug.Assert(bool, string);
Debug.Assert(bool, string, string);

Example:

int interestRate = GetInterestRate();
Debug.Assert((interestRate == 0), “The interest rate is not valid.”);

  • Fail: You may use the Fail method after execute a Boolean condition check to indicate that the result is not the expected one;

Overloads:

Debug.Fail(string);
Debug.Fail(string, string);

Example:

int interestRate = GetInterestRate();
if (interestRate == 0)
Debug.Fail(“The interest rate is not valid.”);

  • Indent: Used to increase the indent level. It’s useful for formatting purposes;

Debug.Indent();

  • Unindent: Used to decrease the indent level. It’s useful for formatting purposes;

Debug.Unindent();

  • Print: The method sends a message to the listener with an end line termination;

Overloads:

Debug.Print(string);
Debug.Print(string, object[]);

  • Write: The method sends a string to a listener;

Overloads:

Debug.Write(object); // Object name
Debug.Write(string); // Message
Debug.Write(object, string); // Object name and category
Debug.Write(string, string); // Message and category

  • WriteIf: The method sends a string to a listener if a Boolean condition is true;

Overloads:

Debug.WriteIf(bool, object); // A condition to check and an object name
Debug.WriteIf(bool, string); // A condition to check and a message
Debug.WriteIf(bool, object, string); // A condition to check, object name and category
Debug.WriteIf(bool, string, string); // A condition to check, message and category

  • WriteLine: The method sends an entire line of text to a listener;

Overloads:

Debug.WriteLine(object); // Object name
Debug.WriteLine(string); // Message
Debug.WriteLine(object, string); // Object name and category
Debug.WriteLine(string, string); // Message and category

  • WriteLineIf: The method sends an entire line of text to a listener if a Boolean condition is true;

Overloads:

Debug.WriteLineIf(bool, object); // A condition to check and an object name
Debug.WriteLineIf(bool, string); // A condition to check and a message
Debug.WriteLineIf(bool, object, string); // A condition to check, object name and category
Debug.WriteLineIf(bool, string, string); // A condition to check, message and category

  • Flush: Sends the content that is in the buffer to the listener.

Debug.Flush();

The following properties are available:

  • Listeners: Gets a collection of trace listeners;

TraceListenerCollection Debug.Listeners;

  • AutoFlush: Gets or sets a Boolean value indicating if the content must be sent to the listener after every write or save to a buffer;

bool Debug.AutoFlush;

  • IndentLevel: Gets or sets the indent level;

int Debug.IndentLevel;

  • IndentSize: Gets or sets the number of characters spaces in an indent.

int Debug.IndentSize;

Trace Class

The trace is class is very similar to the debug class but it works in both debug and release mode and their differences are internal. Based on the fact that most part of the methods and properties listed for the Debug class are the same than the Trace class, I am going to focus only on the different methods and properties available for the Trace class:

  • TraceError: The method writes an error message to all listeners associated to the process;

Overloads:

Trace.TraceError(string);
Trace.TraceError(string, object[]);

  • TraceInformation: The method writes an information message to all listeners associated to the process;

Overloads:

Trace.TraceInformation(string);
Trace.TraceInformation(string, object[]);

  • TraceWarning: The method writes a warning message to all listeners associated to the process;

Overloads:

Trace.TraceError(string);
Trace.TraceError(string, object[]);

  • UseGlobalLock: The property defines if a global lock will be used for the trace.

Trace.UseGlobalLock;

Listeners

Listeners are the objects that will effectively listen for messages and send them to a file, xml, event log and so on. Listeners can be defined either programmatically or from the application’s config file and more than one can be defined for application.

These are some listeners types available:

  • DefaultTraceListener: It sends a message to the default output. For example, if you are running an application within Visual Studio in debug mode, the default behavior is a message box display;
  • XmlTraceListener: It sends a message to a XML file;
  • DelimitedListTraceListener: It sends a message to a Stream or TextWriter object in a delimited text format;
  • EventLogTraceListener: It sends a message to an event log;
  • TextWriterTraceListener: It sends a message to a Stream or TextWriter object;
  • WebPageTraceListener: It sends a message to the web page trace.

How to…

Let’s take a look at how to create a listener that sends the output to a text file.

Creating a trace listener programmatically:

/// Create an instance of the text writer trace listener object.
TextWriterTraceListener tracerWriter = new TextWriterTraceListener(@”C:\example.log”);

/// Remove all listeners.
Trace.Listeners.Clear();

/// Adds the new text writer trace listener.
Trace.Listeners.Add(tracerWriter);

/// Sets the auto flush property to true to enforce
/// all writes to be sent to the output file.
Trace.AutoFlush = true;

Creating a trace listener using a config file:

<configuration>
  <system.diagnostics>
    <trace autoflush=true
>
      <listeners>
        <clear/>
        <add name=
tracerWriter type=System.Diagnostics.TextWriterTraceListener initializeData=C:\example.txt />
      </listeners>
    </trace>
  </system.diagnostics>
</configuration>

Basically the same steps have been performed:

  • Clear the listener collection;
  • Add a new TextWriterTraceListener object indicating the output path and file name;
  • Set the AutoFlush property to true.

Writing data to the listener

Now that you know the methods available, you may use them to write information to the text file:

/// Writes an information message
Trace.TraceInformation(“This is an information message”);

/// Writes a warning message
Trace.TraceWarning(“This is a warning message”);

/// Writes an error message
Trace.TraceError(“This is an error message”);

decimal interestRate = 1.25M;

/// Writes a message if the condition is not true
Trace.Assert((interestRate == 0), “The interest rate is invalid because is not zero.”);

/// Writes a message if the condition is true
Trace.WriteLineIf((interestRate > 0), “The interest rate is greater than zero.”);

/// Writes a message only if is in debug mode
Debug.WriteLine(“This line is printed only in debug mode.”);


Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s

Categories

%d bloggers like this: