My Technical Notes

Tuesday, 24 September 2013

C# Stopwatch code

The following `StopwatchLogger` class logs the interval between logging statements and the total elapsed time:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class StopwatchLogger
{
    public string Name { get; private set; }
    private System.Diagnostics.Stopwatch stopwatch { get; set; }
    private Action<string> LogAction = null;

    private TimeSpan lastElapsed;

    public StopwatchLogger(string name = null)
    {
        this.Name = name;
        stopwatch = new System.Diagnostics.Stopwatch();
        this.lastElapsed = new TimeSpan(0);
    }

    public StopwatchLogger(Action<string> log, string name = null)
        : this(name)
    {
        LogAction = log;
    }

    public void Start()
    {
        this.Start("Stopwatch started");
    }

    private void Start(string message)
    {
        Log(message);
        stopwatch.Start();
    }

    public void Stop()
    {
        this.lastElapsed = stopwatch.Elapsed;
        stopwatch.Stop();
    }

    public void Reset()
    {
        stopwatch.Reset();
        this.lastElapsed = new TimeSpan(0);
    }

    /// <summary>
    /// 
    /// </summary>
    public void Restart()
    {
        this.Reset();
        this.Start("Stopwatch re-started");
    }

    public void Log(string message)
    {
        Log(message, new object[] { });
    }

    public void Log(string format, params object[] args)
    {
        Action<string> logAction = LogAction ?? (s => System.Diagnostics.Debug.WriteLine(s));
        var message = string.Format(format, args);
        var elapsed = stopwatch.Elapsed;
        var difference = elapsed.Subtract(lastElapsed);

        var logMessage = string.Format(/* (Name: ) Interval Elapsed Message */"{0}{1} {2} {3}",
            Name != null ? Name + ": " : "",
            difference, 
            elapsed,
            message);

        logAction(logMessage);

        lastElapsed = elapsed;
    }
}

To use the class, you first call `Start()` and then each time you call `Log` it will log the time last since `Log` was called together with the total elapsed time:


StopwatchLogger watchLogger = new StopwatchLogger();
watchLogger.Start();
Thread.Sleep(2000);
watchLogger.Log("after 2 seconds");
Thread.Sleep(3000);
watchLogger.Log("after another 3 seconds");
Below is what the output would look like for the above code:

00:00:00 00:00:00 Stopwatch started
00:00:01.9999939 00:00:01.9999939 after 2 seconds
00:00:03.0011063 00:00:05.0011002 after another 3 seconds

TODO: Improve the output by rounding the number of seconds so we see "00:00:02" instead of "00:00:01.9999939".

No comments: