You are fighting the classic Windows timer resolution issue. With a twist.
By default, the timer resolution in Windows is 15.6ms, which means that when you start a periodic timer, specifying a 16.7ms interval, you might receive your next event exactly when you expect it or delayed by as much as 15ms. This explains why you are seeing actual intervals of up to 32ms.
As I mentioned above, the 15.6ms is the default timer resolution, but it is possible for an application to change that value. You may ask why the default is not the highest resolution possible (1ms) and as far as I can tell, the primary reason is because a higher resolution results in a higher CPU load, which translates into higher power usage, which again means higher electric cost and shorter battery life for portable devices.
Read more here:
http://msdn.microsoft.com/en-us/windows/hardware/gg463266.aspx[
^]
So, timers are not more accurate in JavaScript than in C#, but in your case it appears so because the browser you are running the JavaScript in, sets the timer resolution to a finer accuracy than the default and since you are not doing the same in your C# program, confusion sets in.
Read more here:
http://www.nczonline.net/blog/2011/12/14/timer-resolution-in-browsers[
^]
timeBeginPeriod()[
^] is used for changing the timer resolution in an application (call
timeEndPeriod()[
^] when you no longer need the accuracy) and I thought there was a .NET equivalent, but I am not seeing it, so it looks like you might have to use P/Invoke.
For more on that, see here:
http://stackoverflow.com/questions/15071359/how-to-set-timer-resolution-from-c-sharp-to-1-ms[
^]
[EDIT]
As I was re-reading my solution, I realized it seems I recommend changing the timer resolution and keep using regular timers in your C# program. That was not my intention, I mentioned the
timeBeginPeriod()
with the idea that you could try it out to see if that solved the problem.
I recommend that you do use the multimedia timers instead, just as you mentioned in your question, but hopefully my answer helps explain why you were getting your results.
[/EDIT]
Soren Madsen