I'm developing Windows 10 Universal App in C#/Xaml, I'm using await Task.Delay(delayInMilliseconds) to suspend a method for given time. My scenario is somewhat realtime, so it's very sensitive to time changes, and I need to make sure that when i suspend a method for let's say 8 millisecods it is suspended for 8 millisecods. I have noticed that the actual time span for which ** Task.Delay ** suspends the method differes from what is passed as delay parameter, for 1 up to 30 ms, the length of "deviation" being different in each call. So, when I want to sleep for 8 milliseconds, my system sleeps for 9 to 39 milliseconds, and this completly ruins my scenario. So, my question what is the best way to substitute ** Task.Delay ** and to achieve good precision? For the time being I use this method:
public static void Delay1(int delay)
{
long mt = delay * TimeSpan.TicksPerMillisecond;
Stopwatch s = Stopwatch.StarNew();
while (true)
{
if (s.Elapsed.TotalMilliseconds > delay)
{
return;
}
}
}
but it guees it consumes a lot of resources, that is 100% of a processor's core. If an user has small number of processor's cores, this would be very insufficient.
Seems like I've found a sattisfactory solution:
new System.Threading.ManualResetEvent(false).WaitOne(delayInMilliseconds) instead of await Task.Delay(delayInMilliseconds);
I've used following code to test both methods:
The code above should take exactly 3 seconds to execute. With METHOD 2 it took around 3300 ms, so the eror is 0.3 ms per call. Acceptable for me. But the METHOD 1 tok around 15 seconds (!) to execute which gives totally unacceptable error for my scenario. I only wonder what's the usage of CPU with Method 2, hope it doesn't use polling, the documentation says something about use of signals but unfortnatelly it doesn't automatically mean that polling isn't used spomewhere else.
In my tests, I found that DispatcherTimer at 20ms intervals will deliver sufficiently smooth animation if you must do it in code. Doing it in XAML is another alternative as already mentioned.
You should use multi-media timers. Those are much accurate. Take a look here: https://social.msdn.microsoft.com/Forums/vstudio/en-US/2024e360-d45f-42a1-b818-da40f7d4264c/accurate-timer
According to msdn it's not possible to achieve more accuracy due to system clock resolution:
After working hard I found a solution to sleep the thread for specific time and the error is just 3 to 4 microseconds on my Core 2 Duo CPU 3.00 GHz. Here it is:
Here is code.(C# code is also given at the end.) Use "ThreadSleepHandler":
Here is example code:
For c# programmers here is code (I have converted this code but I am not sure):
Note: "ThreadSleepHandler" is thread unsafe. You cannot use a single "ThreadSleepHandler" for multiple threads.
The first sleep time will not be enough accurate.