tags:

views:

5090

answers:

4

I'm trying to rebuild an old metronome application that was originally written using MFC in C++ to be written in .NET using C#. One of the issues I'm running into is getting the timer to "tick" accurately enough.

For example, assuming an easy BPM (beats per minute) of 120, the timer should tick every .5 seconds (or 500 milliseconds). Using this as the basis for the ticks, however, isn't entirely accurate as .NET only guarantees that your timer will not tick before the elapsed time has passed.

Currently, to get around this for the same 120 BPM example used above, I am setting the ticks to something like 100 milliseconds and only playing the click sound on every 5th timer tick. This does improve the accuracy quite a bit, but if feels like a bit of a hack.

So, what is the best way to get accurate ticks? I know there are more timers available than the windows forms timer that is readily available in Visual Studio, but I'm not really familiar with them.

+6  A: 

There are three timer classes called 'Timer' in .NET. It sounds like you're using the Windows Forms one, but actually you might find the System.Threading.Timer class more useful - but be careful because it calls back on a pool thread, so you can't directly interact with your form from the callback.

Another approach might be to p/invoke to the Win32 multimedia timers - timeGetTime, timeSetPeriod, etc.

A quick google found this, which might be useful http://www.codeproject.com/KB/miscctrl/lescsmultimediatimer.aspx

'Multimedia' (timer) is the buzz-word to search for in this context.

Will Dean
+1  A: 

What is the C++ application using? You can always use the same thing or wrap the timer code from C++ into a C++/CLI class.

Coincoin
A: 

Timer classes can start behaving strangely when the timer 'tick' event code is not finished executing by the time the next 'tick' occurs. One way to combat this is to disable the timer at the beginning of the tick event, then re-enable it at the end.

However, this approach is not suitable in cases where the execution time of the 'tick' code is not acceptable error in the timing of the tick, since the timer will be disabled (not counting) during that time.

If disabling the timer is an option, then you can also achieve the same effect by creating a separate thread that executes, sleeps for x milliseconds, executes, sleeps, etc...

Brad Barker
But then you can only be sure that the thread sleeps at least x millioseconds; the thread scheduler does not certify that the thread will run at the exact millesond count
Wilhelm
Right. I agree with what you said about not being able to pinpoint the time of the next tick. The point of what I am saying is you don't want to be executing tick event code from a previous tick when your next tick occurs.
Brad Barker
A: 

System.Windows.Forms.Timer is limited to an accuracy of 55 milliseconds...

yazanpro