Search code examples
c#.netmultithreadingthread-safetytrace

How "relevant" is the non-thread-safety of XmlWriterTraceListener?


According to http://msdn.microsoft.com/en-us/library/ms733025.aspx XmlWriterTraceListener is not thread-safe. (I know that Microsoft.VisualBasic.Logging.FileLogTraceListener is, but I think that XmlWriterTraceListener format is much more readable using Microsoft Service Trace Viewer).

However, I "only" use it for a desktop application with the UI thread and a maximum of 2 BackgroundWorkers using the XmlWriterTraceListener as a Source Listener at the same time. How "relevant" is the non-thread-safety in this case, considering performance impact? Tracing messages are written relatively scarely, i.e. not every second.

edit: The UI thread and the Background worker(s) use different TraceSources (each creates their own). The TraceListener (at the moment FileLogTraceListener, as I was unsure about thread-safety) is a static public property in the App class. I add it to the TraceSources in the constructors of the classes owning the TraceSource.


Solution

  • The Trace class has a property, UseGlobalLock which should be true if the underlying listener(s) report that they're not thread-safe.

    In other words, if you're using a trace listener that isn't thread-safe with the Debug or Trace class, then those classes (Trace/Debug) will make sure the underlying listener is handled in a thread-safe manner.

    In other words, your question about how relevant the missing thread safety is for the trace listener, then the answer is not very. It might be relevant from a performance standpoint, if you create a listener there might be some minor performance to gain by making the listener thread-safe, if this can be handled in a different manner than just a global lock around it.

    If you're unsure you can force this property to be true, and the documentation has an example for how to do that here, Trace.UseGlobalLock Property:

    <configuration>
      <system.diagnostics>
        <trace useGlobalLock="false" />
      </system.diagnostics>
    </configuration>
    

    Note that if you're using the trace listener object with something other than the Trace class, then this answer is not applicable.

    Note that the Debug class is using the same underlying framework as the Trace class, but does not have the property.

    The current implementation of Debug and Trace is that they both wrap an internal static class, and thus if you add a debug listener it gets added to trace and vice versa. As such, the property Trace.UseGlobalLock is applicable for Debug.WriteXYZ as well.