Why is Thread.Sleep is not precise for long durations?
I have a service written in C#. Service is active around the clock but one thread sleeps via Thread.Sleep till a predetermined time - typically 9PM - 11pm - to perform some housekeeping tasks. First time service starts, it calculates time span in mseconds till the housekeeping time and calls Thread.Sleep using that time span. Next time the thread simply calls Thread.Sleep(24*60*60*1000) to sleep 24 hours.
It works just fine except a single installation when Sleep wakes few minutes earlier - 5-8 minutes earlier according to the trace log. Over several weeks, housekeeping time shifts few hours. I can expect that the housekeeping time can shift forward - not backwards. Wondering if anyone can have an explanation. I must admit that I am not looking for a diffe开发者_运维知识库rent solution to fix the problem - just trying to explain the behavior.
Thread.Sleep is not designed for long accurate sleeps like you are doing. You should be using somthing like System.Threading.Timer. You can give it a first run time of midnight, and have it go off every 24 hours. the Timer(TimerCallback, Object, TimeSpan, TimeSpan)
constructor is exactly what you are looking for.
Sleep doesn't use wall clock for time calculations. It uses regular interrupt intervals which come approximately every 10ms (adjustable and OS version dependent) for this. The time source which is used for these interrupts is a cheap quartz which was historically was used for some other functions, so its frequency is both not exactly 1/10ms and fluctuates from one machine to another.
The correct approach to solving your problem would be sleeping for much shorter periods of time and checking if the time has come to wake up for real.
Also, here's hoping that when you say you're using Sleep(), in fact you're waiting for an event with a timeout.
精彩评论