views:

175

answers:

1

I have seen other user posts which show Stopwatch measuring time spent in "Thread.Sleep(5000)" to be around 5000ms.

But my program produces the following results

for (int i = 0; i < 20; ++i)
        {
            Stopwatch sw = Stopwatch.StartNew();
            DateTime start = DateTime.Now;
            Thread.Sleep(5000);
            sw.Stop();
            Console.Out.WriteLine("StopWatch Diff:" + sw.ElapsedMilliseconds.ToString()); 
            Console.Out.WriteLine("DateTime Diff:" + DateTime.Now.Subtract(start).TotalMilliseconds.ToString());
        }

StopWatch Diff:1684
DateTime Diff:5262.592
StopWatch Diff:1625
DateTime Diff:4997.12
StopWatch Diff:1604
DateTime Diff:4997.12
StopWatch Diff:1601
DateTime Diff:4997.12
StopWatch Diff:1690
DateTime Diff:4997.12
StopWatch Diff:1603

Is it just me who is observing this behaviour? Why stopwatch measures 1.6 seconds when 5 seconds have actually passed. It is the time that the thread is actually running?

+4  A: 

The Stopwatch class is not reliable.

This is unreliable on processors that do not have a constant clock speed (most processors can reduce the clock speed to conserve energy). This is explained in detail here.

Mark Byers
May be that's the case. Curiously, when I substitute Thread.Sleep(5000) with Thread.SpinWait(100000000) the discrepancy between time measured using Stopwatch and DateTime.Now becomes negligible.
Alexdm
@user426777: When you use SpinWait it keeps the processor busy so it will probably be running at full speed at all times (constant speed). When you use Thread.Sleep, the processor doesn't have anything to do so it might automatically change to a lower clock speed to save power. You could try changing your processor to run at a constant speed and then I think it will work in both cases.
Mark Byers
You are right. When I start another thread which does some work and keeps processor busy, stopwatch shows the correct time. Thanks!
Alexdm