Ehsan
Ehsan

Reputation: 517

dispatcherTimer doesn't work accurately

I need to capture 10 frames per second of a live camera for 15 min. I used dispatcherTimer class but seems it doesn't work accurately. How to make it accurate? I even don't save the image because it is time consuming and i just keep it in the memory but still it doesn't work correctly. should I use another library?

counter01 = new DispatcherTimer();
counter01.Tick += new EventHandler(counter01_Tick);
counter01.Interval = new TimeSpan(0, 0, 0,100); // every 100 milliseconds == 10 frames per seconds

Upvotes: 2

Views: 2584

Answers (3)

Peter Huber
Peter Huber

Reputation: 3312

You actually can get the DispatcherTimer to execute the DispatcherTimer.Tick event every 100 milliseconds on a good PC, but you have to address 2 problems first (see below). However, as others wrote here correctly, the processing of a frame will take some time too and the fastest reliable tick frequency might only be 5 ticks per second, if the frame processing itself takes about 100 milliseconds.

1) Choose higher DispatcherTimer.Priority

The DispatcherTimer runs on the WPF GUI thread. The advantage of this is that the code of DispatcherTimer.Tick can access any WPF control. The WPF GUI thread is controlled by a Dispatcher, which has a priority queue for activities the WPF GUI thread wants to execute. Rendering related activities have a higher priority than the DispatcherTimer has per default. The default priority of the DispatcherTimer is DispatcherPriority.Background. With this priority, the Tick can execute on my PC not faster than every 100..300 milliseconds. However, create the timer like this: new DispatcherTimer (DispatcherPriority.Input) and it will fire about 100..200 milliseconds. Rendering will still have a higher priority, so the user does not get a frozen GUI.

2) Improve Tick regularity

One problem with the DispatcherTimer is that if the Tick event gets delayed by x milliseconds because the WPF GUI thread is busy with other activities, the next Tick will still wait for 100+ milliseconds. However, if you shorten DispatcherTimer.Interval by x milliseconds, you will get a more regular firing of the tick event.

For more details see my article on CodeProject: Improving the WPF DispatcherTimer Precision

Final Consideration

Why do you want to process the frames on the WPF GUI thread ? Use a DispatcherTimer only if the Tick event has little to do and needs access to the WPF controls. However, if you need to execute quite some code every 100 milliseconds, better use an additional thread. Your CPU has different cores and it is a good idea to distribute the workload over 2 cores.

Upvotes: 1

Hans Passant
Hans Passant

Reputation: 941715

It is as accurate as it can be. Which requires your UI thread to be responsive, quickly dispatching any messages it gets. Including the "time is up" notifications that DispatcherTimer generates, the ones that generate the Tick event.

The usual hangup with seeing DispatcherTimer triggering the Tick event handler late is that you have a firehose problem. In other words, the amount of time required by the event handler is longer than the timer's Interval property value. This takes care of itself in the manner you expect, whenever you try to do more than the machine can handle then whatever you are trying to do just runs later.

No lack of firehose problems with video, one frame can contain a lot of data. A typical hidef video stream runs at 25 frames per second with each frame containing 1920x1080 pixels. That's 25 x 1920 x 1080 x 3 = 148 megabytes/second. Short from decompressing overhead, you can't even write the data to a disk at that rate. Most consumer-level disk drives top out at 30 megabytes/second, give or take a factor of 2. Lowering the frame rate to 10/sec is not enough to solve it, that's still 60 MB/sec, you have to take more drastic measures like reducing the frame size. Or use a good video encoder that can compress video real-time.

This is a systemic problem, not a DispatcherTimer problem. Use a profiler to get more insight, it helps you identify the true bottle-neck.

Upvotes: 2

jomsk1e
jomsk1e

Reputation: 3625

MSDN states that:

Timers are not guaranteed to execute exactly when the time interval occurs, but they are guaranteed to not execute before the time interval occurs.

You can check StopWatch, it might help you.

Upvotes: 2

Related Questions