Stumbled upon unexpected behaviours during elapsed time measurements.
I've started from Stopwatch
class:
for (int i = 0; i < 100; i++)
{
var stopwatch = new Stopwatch();
stopwatch.Start();
Thread.Sleep(200);
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds);
}
https://dotnetfiddle.net/3hch1R
But it turned out that every once in a while elapsed time will be less than 200ms.
Then was a time of DateTime.Now
and it showed something strange as well:
for (int i = 0; i < 100; i++)
{
var start = DateTime.Now.Millisecond;
Thread.Sleep(200);
var stop = DateTime.Now.Millisecond;
Console.WriteLine(stop - start);
}
https://dotnetfiddle.net/2vo2yw
Thing as simple as this regularly returns negative results.
So my question is: what is the reason of such behaviour for both classes and how can I measure elapsed time more precisely (without negative deviations) ?
There is a post about stopwatch which shed some light on the topic, but comments there look a bit contradictory.
Edit1:
As AlexD spotted, DateTime.Now.Millisecond
simply returns a millisecond part, not TotalMilliseconds. So this one is clear.
Edit2:
Following suggestions, I've decided to go with DateTime, it's results satisfies my precision requirements:
for (int i = 0; i < 100; i++)
{
var start = (int)DateTime.UtcNow.TimeOfDay.TotalMilliseconds;
Thread.Sleep(200);
var stop = (int)DateTime.UtcNow.TimeOfDay.TotalMilliseconds;
Console.WriteLine(stop - start);
}
Or DateTime.UtcNow.Ticks / TimeSpan.TicksPerMillisecond
if day changing between measurements is a case for you.