Skip to content

Instantly share code, notes, and snippets.

@cliss
Created February 2, 2015 19:07
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cliss/f03f7268a1c9006daf88 to your computer and use it in GitHub Desktop.
Save cliss/f03f7268a1c9006daf88 to your computer and use it in GitHub Desktop.
C# Debug Timer
public class DebugTimer : IDisposable
{
private readonly System.Diagnostics.Stopwatch _watch;
private readonly string _blockName;
/// <summary>
/// Creates a timer.
/// </summary>
/// <param name="blockName">Name of the block that's being timed</param>
public DebugTimer(string blockName)
{
_blockName = blockName;
_watch = System.Diagnostics.Stopwatch.StartNew();
}
public void Dispose()
{
_watch.Stop();
GC.SuppressFinalize(this);
System.Diagnostics.Debug.WriteLine(_blockName + ": " + _watch.Elapsed.TotalSeconds + " seconds.");
}
~DebugTimer()
{
throw new InvalidOperationException("Must Dispose() of all instances of " + this.GetType().FullName);
}
}
public void Foo()
{
using (new DebugTimer("Foo()"))
{
// Do work
}
}
// In the Visual Studio Output window:
// Foo(): 1.2345 seconds.
@gibwar
Copy link

gibwar commented Feb 3, 2015

If you're able to target C# 5/.Net 4.5 you can save yourself from potential refactoring issues falling out of sync by using the CallerMemberName Attribute.

public DebugTimer([System.Runtime.CompilerServices.CallerMemberName] string methodName = "") {
  _blockName = methodName;
  //...
}
/* ... */
public void Foo() {
  using (new DebugTimer()) {
    // Do work
  }
}

// In output window:
// Foo: 1.2345 seconds.

If you might need to call it in different places in the same method, you can extend the constructor to take an extra parameter to capture that info.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment