Reputation: 37182
I'm writing an RTP server to publish PCMA wave files. It needs to pump data every 20ms (on average - it can be a bit either side of that for any 1 pump, but must average out at 20ms).
My current implementation uses a Timer, but then the event fires just over every 20 ms, so it gradually drifts out.
Is there a better way to do this? The only way I can currently think of is to dynamically adjust the timer inteval as it starts to creep, in order to bring it back in line.
void Main()
{
System.Timers.Timer timer = new System.Timers.Timer();
// Use a stopwatch to measure the "wall-clock" elapsed time.
Stopwatch sw = new Stopwatch();
sw.Start();
timer.Elapsed += (sender, args) =>
{
Console.WriteLine(sw.ElapsedMilliseconds);
// Simulate doing some work here -
// in real life this would be pumping data via UDP.
Thread.Sleep(300);
};
timer.AutoReset = true;
// I'm using an interval of 1 second here as it better
// illustrates the problem
timer.Interval = 1000;
timer.Start();
}
Output:
1002
2001
3002
4003
5003
6005
7006
8007
9007
10017
11018
12019
13019
14020 <-- By this point we have creeped over 20 ms in just 14 iterations :(
Upvotes: 2
Views: 863
Reputation: 50672
First of all: I will never get it to be exact because your program will never be in full control of what the CPU's are doing as long as you are running on standard Windows because it is not a real-time OS. Just think of a anti virus kicking in, the Garbage Collector freezing your thread, playing a game on the side, ...
That said you might be able to compensate a bit.
When the handler kicks in, pause the timer, record the current time, act, update the time's interval by setting the interval to the required interval based upon the start of the handler and the time it has taken to act.
This way you can control the creeping better. An exception to that might be when the acting takes longer than the interval and whether the interval should contain the time to act or be the time between to acts.
In my experience you cannot rely on any timer to get an interval that small (20 ms) accurately but compensating for creep can help quite a bit.
Upvotes: 2