stopwatch

.NET Stopwatch meet IDisposable

You’re probably aware of the .NET Stopwatch class, a System.Diagnostics class that ‘Provides a set of methods and properties that you can use to accurately measure elapsed time’.

A code sample illustrates its typical usage:

Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
Thread.Sleep(10000);
stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopWatch.Elapsed;

You get the idea – create, start, execute code (thanks Thread.Sleep(…)), stop and examine its Elapsed property.

There are a number of open source profilers such as Prof-It that provide comprehensive timing information, and there can be some discrepancies when timing code execution with a Stopwatch, as this excellent Code Project article explains, it’s often sufficient to temporarily put in a Stopwatch block to time a piece of code.

One thing to note from the code sample is that it is a little verbose.  The Thread.Sleep(…) call is trivial, for our example, but if we’re timing several lines, the various Stopwatch boilerplate lines rather get in the way.

Wouldn’t it be nice if we could write something like this:

using (new CleverTimer()))
{
	Thread.Sleep(10000);
}

We can, with this little ‘CleverTimer’ class, which uses a mix of a Stopwatch and IDisposable:

public class CleverTimer : IDisposable
{
	private readonly Stopwatch _stopwatch;
	private readonly Action<Stopwatch> _action;
	public CleverTimer(Action<Stopwatch> action = null)
	{
		_action = action ?? (s => Console.WriteLine(s.ElapsedMilliseconds));
		_stopwatch = new Stopwatch();
		_stopwatch.Start();
	}
	public void Dispose()
	{
		_stopwatch.Stop();
		_action(_stopwatch);
	}
	public Stopwatch Watch
	{
		get { return _stopwatch; }
	}
}

The class has a couple of members – the all important Stopwatch, as well as an Action of type Stopwatch.  The constructor can accept an Action, but defaults to writing out the Elapsed milliseconds of the stopwatch.   The constructor creates a the member Stopwatch and starts it.

The Dispose method, required for the implementation of the IDisposable interface, simple stops the Stopwatch member and invokes the _action code.

It’s all fairly simple stuff, but goes some way to simplifying timed code.