- Home /
Accurate millisecond timed thread
Hello everyone,
I'm using a mathematic gradient algorithm for calculations of stuff. This algorithm has to run every couple of milliseconds. At the moment, I'm creating a thread and use the Thread.Sleep() command like this.
private void Start ()
{
// Start the thread that will be the SuperFastLoop
updateThread = new Thread(SuperFastLoop);
updateThread.Priority = System.Threading.ThreadPriority.Highest;
updateThread.Start();
}
private void SuperFastLoop()
{
// This begins our Update loop
while (true)
{
if (SerialComm.Streaming)
{
// Do Algorithm stuff here
}
Thread.Sleep(DelayMs);
}
}
As far as I've seen, Thread.Sleep() is called a beginner's tactic and "one should do it better", but I have evaluated and tested the common alternatives, and they're not suitable for a delay of around 1 ms. Basically, my question is: Is there a proper or better way to have a sharp 1 ms delay between function calls, at best including the algorithm calculation time, on multiple platform?
5 ms would also be suitable and are actually used by now. But I would have it dependent on the system and its power. I has to be way faster than FixedUpdate() and should not be calculated here, as I don't want to mess with all physics due to that.
We intend to use this on these platforms: Windows, Mac, Android, iOs.
Answer by ivan866 · Jun 05, 2019 at 09:50 AM
You need a cpp program to get a <=1 ms timing accuracy on Windows.
That's nonsense. The used language does not improve any OS API call resolution. Windows internal tick timer has a poor resolution. See this SO question (which is actually about a C++ program).
Here's an example high precision timer class in C# that is based in the Stopwatch class. Though keep in $$anonymous$$d that when requesting "rather high" callrates it will actually busy-wait (using Thread.SpinWait) which would cause 100% usage of one core. That doesn't mean the core can't be used for anything else just that the thread never actually actively yields it's assigned time slice.
Answer by EternalClickbait · Jun 05, 2019 at 11:13 AM
I would use the System.Diagnostics.Stopwatch
class.
Make a long for the last time the function ran. Then use a while loop to wait until that time is at least 1ms smaller than the current time. Some (unrun) code:
Stopwatch s = Stopwatch.StartNew();
Start:
long lastTime = 0;
int delayTime = 1; //ms
s.Start();
while ((s.ElapsedMilliseconds - lastTime) < delayTime) ;
lastTime = s.ElapsedMilliseconds;
DoStuff();
goto Start;
I think this is the right way to do it. It should wait the same amount of time no matter how long your code takes (as long as your code takes less time than delayTime
Also, what sort of things do you need to do? Why do you need the wait in the first place?