What .NET object (or technique) is the most precise at launching a thread every XXX milliseconds? What are the tradeoffs?
For example:
int maxDurationMs = 1000;
while (true)
{
DateTime dt = DateTime.UtcNow;
DoQuickStuff()
TimeSpan duration1 = DateTime.UtcNow - dt;
int sleepTime = maxDurationMs - duration1.Milliseconds;
if (sleepTime > 0)
System.Threading.Thread.Sleep(sleepTime);
}
or
// CPU Intensive, but fairly accurate
int maxDurationMs = 1000;
while (true)
{
DateTime dt = DateTime.UtcNow;
DoQuickStuff()
while (true)
{
if (dt.AddMilliseconds(maxDurationMs) >= DateTime.UtcNow)
break;
}
}
Alternate methods of doing the same thing, but with varying degrees of accuracy and tradeoffs (CPU, etc)
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.
Don't use DateTime: its accuracy is limited to around 16ms on most systems. (See Eric Lippert's blog)
The most accurate method would be to have a dedicated thread running a while loop with a System.Diagnostics.Stopwatch object to count the time.
Even with the most precise and accurate timer in existance, raising an event exactly every x milliseconds is no simple task given the unpredictability of CPU time slices: I suggest looking into how games do their main loop (achieving a stable 30fps with lag compensation, for instance). A good example is OpenTK's GameWindow, specifically the RaiseUpdateFrame method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With