How accurate is Thread.Sleep(TimeSpan)?
Your thread is sharing CPU Time with other threads. The Sleep will end as soon as it is your turn again and the kernel notices the sleep time has elapsed, so it is not that accurate.
CPU load, process priorities, number of concurrent threads, even from other processes, will have effect upon it.
What Thread sleep method is most precise: Monitor.Wait vs System.Timer vs DispatchTimer vs Threading.Timer
I have never actually used them myself, but Multimedia Timers are said to have the best resolution of any timer service in Windows. The .NET BCL does not have a wrapper for this timer service yet so you will have to do the P/Invoke calls yourself.
Another option might be to use Stopwatch
together with some standard Thread.Sleep
calls in a tight loop. I am not sure how much luck you would have with this approach, but it might be more accurate than a plain old Thread.Sleep
call by itself. I have never tried it, but anything is worth a shot I suppose.
I did some experiments and I discovered that changing the thread priority to ThreadPriority.Highest
made a considerable difference. It reduced the standard deviation of the interval by quite a bit on each technique I tried.
Why is Thread.Sleep so harmful
The problems with calling Thread.Sleep
are explained quite succinctly here:
Thread.Sleep
has its use: simulating lengthy operations while testing/debugging on an MTA thread. In .NET there's no other reason to use it.
Thread.Sleep(n)
means block the current thread for at least the number
of timeslices (or thread quantums) that can occur withinn
milliseconds.
The length of a timeslice is different on different versions/types of
Windows and different processors and generally ranges from 15 to 30
milliseconds. This means the thread is almost guaranteed to block for
more thann
milliseconds. The likelihood that your thread will
re-awaken exactly aftern
milliseconds is about as impossible as
impossible can be. So,Thread.Sleep
is pointless for timing.Threads are a limited resource, they take approximately 200,000 cycles
to create and about 100,000 cycles to destroy. By default they
reserve 1 megabyte of virtual memory for its stack and use 2,000-8,000
cycles for each context switch. This makes any waiting thread a
huge waste.
The preferred solution: WaitHandles
The most-made-mistake is using Thread.Sleep
with a while-construct (demo and answer, nice blog-entry)
EDIT:
I would like to enhance my answer:
We have 2 different use-cases:
We are waiting because we know a
specific timespan when we should continue (useThread.Sleep
,System.Threading.Timer
or alikes)We are waiting because some condition changes some time ...
keyword(s) is/are some time! if the condition-check is in our code-domain, we
should use WaitHandles - otherwise the external component should
provide some kind of hooks ... if it doesn't its design is bad!My answer mainly covers use-case 2
Why is Thread.Sleep is not precise for long durations?
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.
.net thread.sleep inaccurate
As mentioned, accurate timings generally need a thread/process that is not going to time sliced out, to do this, you must Spin
rather than Sleep
.
Option 1
If you want absolute accuracy over anything else, I would use a dedicated high priority thread with a Stopwatch.
bool running = true;
Thread t = new Thread(() =>
{
Stopwatch sw = Stopwatch.StartNew();
while (running)
{
if (sw.ElapsedMilliseconds >= 20)
{
RunCode();
sw.Restart();
}
}
}) { Priority = ThreadPriority.Highest, IsBackground = true };
t.Start();
// ...
running = false;
t.Join();
Option 2
Bit more slimmed down, doesn't run on a different thread but still spins.
while (true)
{
SpinWait.SpinUntil(() => false, TimeSpan.FromMilliseconds(20));
RunCode();
}
Option 3
Some open source high resolution timer code. e.g. https://gist.github.com/HakanL/4669495
Using Delay(TimeSpan) or Thread.Sleep doesn’t properly work in VMware
I can unfortunately not help you with fixing the VMWare end, aside from two off ideas:
If there is anything that passes through Threads directly to the Host CPU, you could try turning them off. It would be bad for performance, but might avoid issues with the Thread (Manager) and starting OS running on slightly different clocks.
I do I have a different approach you could try. One that relies a whole lot less on Thread/Async and similar Delay systems. Something that might be slightly more robust, against whatever is causing this. This difference was purely by accident - it started it's live as a example for a very basic Rate Limiting System, to be run in a seperate thread:
integer interval = 20;
DateTime dueTime = DateTime.Now.AddMillisconds(interval);
while(true){
if(DateTime.Now >= dueTime){
//insert code here
//Update next dueTime
dueTime = DateTime.Now.AddMillisconds(interval);
}
else{
//Just yield to not tax out the CPU
Thread.Sleep(1);
}
}
This one only uses the Thread mechanics for the "low CPU load when idle" part. Everything else is based on the hopefully more stable DateTime System.
Do note that short Intervalls are poorly supported, even 20 ms might already be beyond the limit. DateTime.Now() is not remotely as accurate as as the type can be precise, so it only remotely works for dual or tripple digit Intervalls. Delay and Sleep do actually support Millisecond precision.
Does Threading.Thread.Sleep accepts ticks?
That falls in the "it depends" category. You could, say, be using it in a Silverlight app that runs on a Mac. But a standard Windows desktop app uses the operating system's Sleep() call which accepts a sleep time expressed only in milliseconds.
That's not where it ends, by default Windows can only sleep a thread with an accuracy that depends on the operating system clock interrupt. Which is, by default, 1/64 of a second, 0.015625 seconds on most machines. So if you Thread.Sleep(1) then you'll actually sleep for about 16 milliseconds. Or more.
You can jack up the interrupt rate by pinvoking timeBeginPeriod(1). Sleeps are now accurate to a millisecond, plus or minus a bunch due to scheduling inaccuracies. Something you should never do on a battery-powered machine. And don't forget to pinvoke timeEndPeriod().
Why does Thread.Sleep() method sleep more than expected?
Console.Read()
reads a character, and then you convert it's ASCII code to int
.
This prints 53
if you enter 5
:
Console.WriteLine("{0}", Console.Read());
BTW, you multiply 5 by 1000, and then sleep for already multiplied value. So the overall time of sleeping in the loop seems to be 5 * 5 * 1000
, not 5 * 1000
ms. Is it intentional?
Related Topics
How to Find the State of Numlock, Capslock and Scrolllock in .Net
Lambda Expression Not Returning Expected Memberinfo
Wix - How to Run/Install Application Without Ui
Non-Static Method Requires a Target
How to Use Showdialog Without Blocking All Forms
Pulling Data from a Webpage, Parsing It for Specific Pieces, and Displaying It
Why C# Is Not Allowing Non-Member Functions Like C++
Synchronized Scrolling of Two Scrollviewers Whenever Any One Is Scrolled in Wpf
Request Windows Vista Uac Elevation If Path Is Protected
What Is the "Right" Way to Bring a Windows Forms Application to the Foreground
How Accurate Is Thread.Sleep(Timespan)
C# Generic Inheritance and Covariance Part 2
Why Are C# Interface Methods Not Declared Abstract or Virtual
How to Create a Xsd Schema from a Class
How to Merge 2 List<T> and Removing Duplicate Values from It in C#
How to Use Xpath with Xdocument
How to Delete a File Which Is Locked by Another Process in C#