Getting started

edit

Install the package

Add the Meziantou.Framework.ValueStopwatch package to a project:

dotnet package add Meziantou.Framework.ValueStopwatch

The examples of this documentation omit the using directives: they need using Meziantou.Framework;.

Measure an operation

Start the stopwatch before the operation, and read the elapsed time after it:

// Start a new stopwatch
ValueStopwatch stopwatch = ValueStopwatch.StartNew();

// Get elapsed time
TimeSpan elapsedTime = stopwatch.GetElapsedTime();

StartNew records the current timestamp. GetElapsedTime returns the time elapsed since then, as a TimeSpan.

Read the elapsed time several times

The stopwatch never stops. Each call to GetElapsedTime measures the time since StartNew, so you can read intermediate durations, for instance the time to the first byte and the total time of a request:

var stopwatch = ValueStopwatch.StartNew();

TimeSpan first = stopwatch.GetElapsedTime();
TimeSpan second = stopwatch.GetElapsedTime();

// The stopwatch never stops: each call measures the time since StartNew
Assert.True(second >= first);

To measure a new interval, assign a new stopwatch: stopwatch = ValueStopwatch.StartNew();.

A stopwatch that was never started

default(ValueStopwatch), which is also the value of a field that was never assigned, was never started. IsActive tells whether a stopwatch was created by StartNew, and GetElapsedTime throws an InvalidOperationException on a stopwatch that was not:

// A default ValueStopwatch was never started
ValueStopwatch stopwatch = default;
Assert.False(stopwatch.IsActive);
Assert.Throws<InvalidOperationException>(() => stopwatch.GetElapsedTime());

stopwatch = ValueStopwatch.StartNew();
Assert.True(stopwatch.IsActive);
Assert.True(stopwatch.GetElapsedTime() >= TimeSpan.Zero);

Check IsActive before reading a stopwatch that may not have been started, for instance a field set when an operation begins and read when it ends.

Next steps

  • Timestamps: measure between two timestamps that you store yourself.