Callback Trace Listener

Reading Time: 2 minutes

lightSo you know about the Trace facility in System.Diagnostics, right? If not then you should because it’s really rather handy. It provides a set of static methods that you can call to write out trace information to any number of connected “Listeners” which you can define in code or in config.
The default trace listener writes to the Win32 OutputDebugString stream, you can view this in Visual Studio’s “Output” window or using a viewer such as Sysinternals DebugView.

Sure if you need more extensive logging and tracing then you should look to something like log4net, but if your requirements are simple then System.Diagnostics.Trace and System.Diagnostics.Debug are really handy.

Anyway, that’s not the point of this article.

Quite often I end up writing non-production apps – little gizmos for this or that – which could do with informing the user of what’s going on via some sort of rolling log on the UI.

So I wrote this tiny little class to help.

public class CallbackTraceListener : TraceListener
{
    public event Action<string> WriteToOutput;

    public override void Write(string message)
    {
        if (null != WriteToOutput)
            WriteToOutput(message);
    }

    public override void WriteLine(string message)
    {
        Write(message + Environment.NewLine);
    }
}

It’s a Trace Listener just like the one that writes to OutputDebugString. You need a little bit more code to make it work, in the initialisation of the your application you need to register an instance of it as a trace listener…

public MainWindow()
{
    var uiTracer = new CallbackTraceListener();
    uiTracer.WriteToOutput += UiTracer_WriteToOutput;
    uiTracer.Name = "UITraceListener";
    Trace.Listeners.Add(uiTracer);
    Trace.WriteLine("Debug window initialised");
    Trace.WriteLine("Ready...");
    InitializeComponent();
    ...
}

Now every time you use any of the Trace methods that write output, the UiTracer_WriteToOutput callback will be called with the string that’s written. You can add the strings to a ListBox, or put them through any other kind of processing you want.
It’s a really simple and useful way to subscribe to up your own Debug/Trace stream.