Debugging and Tracing with C# and ASP.NET Framework

Debug and Debugger classes are very important when we try to see if our code execution is as planned and also to keep track of bugs after production deployment.

Debugger class Methods

 

NameDescription
Break Signals a break to the debugger
IsAttached Checks if the debugger is attached to a process
IsLogging Checks if the Debugger is currently logging
Launch Launches a debugger, and attaches it to a process
Log Posts a message to the debugger

String MyMessages = ReturnMessage();
if (MyMessages == null)//we use if
{
  Debugger.Break();
}

It is important to remember that Debugger only works if code is compiled in Debug mode, if code is compiled for the release all debugging code will not be compiled into dll and will be ignored.

Log method direct error messages to listeners. One of such listeners is DefaultTraceListener. It takes Log methods and writes them out into target source.
Trace.Listeners.Clear();
DefaultTraceListener MyListener = new DefaultTraceListener();
Trace.Listeners.Add(MyListener);
Debugger.Log(2, "Test", "test");
Console.ReadLine();

There is another more powerful class called Debug with the following methods.

 

NameDescription
Assert Evaluates a condition, and displays a message
Close Flushes the output buffer
Fail Outputs a failure message
Flush Flushes the output buffer
Indent Increments the indent level by one
Print Writes a message followed by a line
Unindent Opposite of the Indent method
Write Writes information about attached Debug
WriteIf Performs the same action as the Write method
WriteLine Writes information about attached Debug or Trace
WriteLineIf Performs the same action as the WriteLine method

Debug has powerful method called Assert. We cannot always run line by line debugging especially if we have program which is 50,000 lines long, so instead we’ll be using Assert wherever we have condition such as true or false. We call it like that Debug.Assert.
NameValueCollection MySetting = ConfigurationManager.AppSettings;
Debug.Assert(MySetting != null && MySetting["Fool"] != null, "There was a problem");
Console.WriteLine(MySetting["Fool"]);

Simply by running program we could see potential issues. This is especially useful if we are running every day builds and we want to validate all of the checked in code. Simpler version is Debugger.Fail which does not use condition, but rather display messages.
NameValueCollection MySetting = ConfigurationManager.AppSettings;
if(MySetting["Fool"] == null)
Debug.Fail("Configuration Setting is Missing");

Debugger Attributes are very handy when we deal with code and how we want to see debuggin information.

For instance, DebuggerDisplayAttribute. This attribute provides a single line summary of the type within the data window of the debugger.
DebuggerDisplay("Employee ( {FullName} )")]
public class Employee
  {
    ooo
  }

There are several attributes.

DebuggerBrowsableAttribute uses enumeration to suppress certain displays

 

NameDescription
Never Element will never be visible
Collapsed Shows the element in a collapsed state
RootHidden Does not display the root element

DebuggerDisplayAttribute displays literal or value

DebuggerHiddenAttribute cannot set breakpoint within code with this attribute

DebuggerNonUserCodeAttribute Debugger will step over code with this attribute

DebuggerStepperBoundaryAttribute helps to view specific portion of the code

DebuggerStepThroughAttribute step over code with this attribute and not show in debug

DebuggerTypeProxyAttribute it override how a given type is displayed

DebuggerVisualizerAttribute use IntelliSense style to show object info

Trace Class is similar to Debug but can be executed inside Debug code as well as Release code. Trace class shares many similarities with Debug and following is a list of methods.

 

NameDescription
AutoFlush Automatically flushed after every write operation
Close Flushes the output buffer
Fail Emits an error message
Flush Flushes the output buffer
Indent Increments the current IndentLevel
IndentLevel Gets or sets the IndentLevel
IndentSize Gets or sets the number of spaces in an Indent
Listeners Gets the collection of listeners
Refresh Refreshes the trace information
TraceInformation Writes an information message
TraceWarning Writes a warning message
Unindent Decrements the IndentLevel
UseGlobalLock Gets whether a GlobalLock should be issued
Write Writes information about attached Debug
WriteIf Performs the same actions as the Write method
WriteLine Writes information about attached Debug
WriteLineIf Performs the same actions as the WriteLine method

Trace Level enumeration

 

TraceLevel enumerationNumerical Value
TraceLevel.Off 0
TraceLevel.Error 1
TraceLevel.Warning 2
TraceLevel.Info 3
TraceLevel.Verbose 4

TraceSource is used by application when we need to produce traces which are associtated with the application. We can use TraceSource to trace events, trace data and information.

It has following methods:

 

NameDescription
Close Closes all the trace listeners
Equals Determines whether two Object instances are equal
Flush Flushes all the trace listeners in the trace listener collection
GetHashCode Serves as a hash function for a particular type
GetType Gets the Type of the current instance
ReferenceEquals Determines whether the specified Object instances are the same instance
ToString Returns a String that represents the current Object
TraceData Writes trace data to the trace listeners in the Listeners collection
TraceEvent Writes a trace event message to the trace listeners in the Listeners collection
TraceInformation Writes an informational message to the trace listeners in the Listeners collection
TraceTransfer Writes trace transfer message to the trace listeners in the Listeners collection

TaceEvent takes TraceEventType enumeration such as Warrning, Error, Critical. If we specifiy Warrning then all three will be traced, if we specify Error then only Error and Critical will be traced.