Helixoft Blog

Peter Macej - lead developer of VSdocman - talks about Visual Studio tips and automation

How To Use TRACE In VS

I must say that I ignored Trace object and TRACE compilation constant for long time. I've been only using Debug object and DEBUG constant for debugging purposes.

Recently, one user of our VSdocman encountered strange problem which I couldn't reproduce. We all know it. So I created special tracing build for him which logged all important activity, variable values and obviously exceptions. The problem was isolated and fixed in one day.

So, how can Visual Studio and .NET framework help us with the tracing? We can use built-in Trace class. This class works similarly to Debug class. It is only compiled into your assembly if TRACE constant is True. VS automatically sets TRACE constant to True for both Debug and Release configurations. You can change this constant in your project properties. Go to Configuration Properties, Build and check or uncheck Define TRACE constant. I have disabled this in "Release" configuration and created a copy of "Release" configuration (see here for more info) named "Release with Trace" where I enabled TRACE.

Now I only put Trace.WriteLine in the code. You can also use more complex methods of Trace class, define conditions, error levels etc. I won't describe them here.

But wait, is that all? Not at all. There are several issues related to tracing.

  1. You might thing that all code containing Trace won't be compiled if TRACE constant is false. This is not true. If you look at Trace members documentation, you will notice that only Trace methods have set <Conditional("TRACE")> attribute. ConditionalAttribute class is very interesting attribute which causes that calls to methods with this attribute are ignored and not compiled. But Trace properties don't have <Conditional("TRACE")> specified so they are always compiled. For example Trace.Listeners is always compiled and you may fall in troubles if you don't keep it in mind. If you don't want to compile this code if TRACE=False, then use standard conditional compilation statement:
    #If Trace Then
    ...
    #End If
  2. Write variables with Nothing (null) value correctly. Nothing value is very common reason why your program doesn't work as expected. I'm using the following function:
    #If Trace Then
    '''<summary>
    ''' The same as Object.toString but handles Nothing correctly.
    '''</summary>
    Friend Function toStr(ByVal obj As Object) As String
        Try
            If obj Is Nothing Then
                Return "Nothing"
            Else
                Return obj.ToString
            End If
        Catch ex As Exception
            Return "Nothing"
        End Try
    End Function
    #End If
  3. You probably want your tracing information be written in file so the end-user can send it to you. You need to add your own listener to Trace class. The following code writes the log information into USER_APP_DATA\VSdocman\trace_log.txt file. You need to place it in your code before any other Trace method is used.
    #If Trace Then
       Try
           Dim myTextListener As TextWriterTraceListener
           Dim userAppData As String
           userAppData = System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
           ' Create a file for output named trace_log.txt in Application data folder.
           IO.Directory.CreateDirectory(IO.Path.Combine(userAppData, "VSdocman"))
           Dim myFile As IO.Stream = IO.File.Open(IO.Path.Combine(userAppData, "VSdocman\trace_log.txt"), _
               IO.FileMode.Create, IO.FileAccess.ReadWrite, IO.FileShare.Read)
           ' Create a new text writer using the output stream, and add it to
           ' the trace listeners.
           myTextListener = New TextWriterTraceListener(myFile)
           Try
               If TypeName(myTextListener.Writer).Equals("StreamWriter") Then
                   CType(myTextListener.Writer, IO.StreamWriter).AutoFlush = True
               End If
           Catch e As Exception
           End Try
           Trace.AutoFlush = True
           Trace.Listeners.Clear()
           Trace.Listeners.Add(myTextListener)
       Catch ex As Exception
       End Try
    #End If

 

Comments are now closed for this entry

 

Start generating your .NET documentation now!
DOWNLOAD
Free, fully functional trial