.Net Stopwatch Returns Negative Elapsed Time

The System.Diagnostics.Stopwatch class in the .Net runtime can be used to time operations. Bit there’s a problem in .Net 3.5 and earlier. The Elapsed* properties (Elapsed, ElapsedMilliseconds, ElapsedTicks) will sometimes return a negative value.

There’s a note in the documentation:

On a multiprocessor computer, it does not matter which processor the thread runs on. However, because of bugs in the BIOS or the Hardware Abstraction Layer (HAL), you can get different timing results on different processors. To specify processor affinity for a thread, use the ProcessThread.ProcessorAffinity method.

Some advocate setting processor affinity to eliminate the possibility of a negative elapsed time. But a common work-around is to simply use zero whenever the elapsed time is negative.

In recent work I used the Stopwatch class to time operations performed by Threads in a ThreadPool and I was getting false timings because of the negative elapsed time issue. I was leery of messing with the threads’ processor affinities because the ThreadPool is a shared resource. But I had concerns about the ‘convert to zero’ work-around.

Through a Microsoft contact I was able to confirm that the work-around of checking for ‘elapsed < 0’ is adequate. The negative time issue occurs only when measuring very small time periods. The issue is fixed in .Net 4.0 and the fix in the Stopwatch is to check that if elapsed < 0 then set elapsed to zero.