I am using timer to scroll the list. Every millisecond interval i am initiating the Tick event. Event though the animation looks very slow.
repeatTimer_Tick(this, new EventArgs());
repeatLeftTimer.Interval = TimeSpan.FromMilliseconds(1);
repeatLeftTimer.Tick += new EventHandler(repeatTimer_Tick);
The timers in windows have a resolution of several milliseconds, IIRC, something between 10 and 50 ms. You can't get the normal timer to tick every millisecond.
I would try to use an animation for what you're doing.
The .NET timer classes generally have a minimum interval of 15.6 ms. If you need a faster increment (down to 1ms) Windows provides a multimedia timer in the unmanaged API. You could import this timer and use it -- I've done it and it works.
I based my code off of this: http://www.codeproject.com/KB/miscctrl/lescsmultimediatimer.aspx
Should be most of what you need; I added some code to look at the high resolution timer and observe the time between ticks -- I was able to get it to 1ms, += 0.10 ms
You have two good and (relatively) easy options:
Use an animation - WPF has a very versatile animation system that is likely to be able to do what you need.
Use the CompositionTarget.Rendering Event, those are called as fast as possible (each frame) and you are responsible in each call to set the current status based on the current time (that is how the built in animations work)
If you need a high resolution then I would suggest looking into the Stopwatch class. Use the Frequency field and the ElapsedTicks property to get the resolution you are looking for. Note though that the resolution of the stopwatch will change depending on the hardware. Read the link to the msdn documentation for more information.
Related
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
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.
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.
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.
I am doing a simple high score add-in for a game. For this, I need a precise timer from which I can display the elapsed time in a Label. I have so far tried the following:
Windows.Forms.Timer: does not keep high resolution intervals, some are slower, some are faster.
System.Diagnostics.Stopwatch: no tick event.
I also thought of implementing a low-resolution Forms.Timer. Then, when the timer starts and stops I would store the system time and just subtract them to get the elapsed time. But I don't want to over-complicate things. Any ideas?
I don't think it would be overcomplicated to use a combination of a Stopwatch (for its high resolution) and the low-resolution Windows.Forms.Timer.
The Stopwatch is extremely straightforward to use, so it adds very little complexity to using a Timer too.
(This assumes you are ok with high-resolution elapsed time display but with a lower-resolution update interval.)
Use elapsed time since some moment. Than either:
Pick any timer, set it for 15ms and display elapsed time on each tick (should be ok if you are dealing with WinForm/WPF controls)
On every frame refresh display new value (if your code get notified/invoked on every frame refresh)
If you're willing to take the dependency, you could use Reactive Extensions (Rx) to get a timer:
var timer = Observable.Interval(TimeSpan.FromMilliseconds(15))
.Subscribe(() => /* handler */ );
Rx will make sure that the handler is called on the same thread the subscription was created on, and under the covers it uses System.Threading.Timer so it has pretty high and consistent resolution.
I'm pretty frustrated about this one ..
I have a timer called timer1 and a text box called TimeElapsedTextBox and a double variable called TimeTakenToFinish
the timer ticks every 1 second (1000 millisecond)
in the text box, I want it to display the time in this format:
Seconds.PartsOfSecond
Here is the Tick event:
private void timer1_Tick(object sender, EventArgs e)
{
TimeTakenToFinish += (double)timer1.Interval / 10000;
TimeElapsedTextBox.Text = TimeTakenToFinish;
}
it is actually displaying it in the text box the way i want it,
but it's not counting properly ..
I mean, it's counting less than a real second..
could you please tell me how to fix this ..
Your problem here is a misunderstanding of the way your OS works. Sure, you can set the interval to 1000ms, but you cannot expect it to actually tick every second. You are running code on Windows, not a hard (or soft) real time operating system.
As an aside, you should also know that the resolution of your timer is finite, and as of today, limited to the accuracy of your system timer, which is probably about 15ms.
You cannot expect your code to perform that deterministically in that sort of environment. At any point the OS can preemptively kick you out of the CPU and start working on another task.
You simply cannot get the accuracy you desire, though I would ask; is it actually required? Probably not, but you haven't told us what you are actually trying to accomplish here, so who knows?
Also, this is wrong:
TimeTakenToFinish += (double)timer1.Interval / 10000;
Interval is a property which is used to tell the timer roughly how often it should fire the Tick event. You are not actually measuring anything, you may as well just be adding 1000.0 / 10000 to your counter every time.
If you need more precision use the StopWatch class which uses your CPU's high performance timer if available. You can still use a timer to periodically update the UI based on the current elapsed value of the Stopwatch, i.e.,
void timer1_Tick(...)
{
var totalSeconds = _someStopwatch.ElapsedMilliseconds / 1000.0;
TimeElapsedTextBox.Text = totalSeconds.ToString();
}
Instead of using a timer, record the start time using DateTime.Now and then subtract the current time (DateTime.Now) from the start time. This will give you a more accurate timer as it uses the system clock instead which isn't affected so much by CPU performance.
Alternatively you can use System.Diagnostics.Stopwatch which does this for you.
You can still use an ordinary timer with an interval of less than a second to refresh the label displaying the time.
I am making a small typing test in C# in which the program asks you to type a word and then shows you your time.
I was using the c# timer class (drag and drop a timer from the toolbox), with a Tick time of 1ms, however it wasn't giving me accurate results, so I substituted it for a StopWatch , so now the timing is super accurate, but the problem is that it seems that you cannot assign event handlers to a StopWatch so although I can show the user his time when he FINISHES the word, I cannot actually show hum the time WHILE he is typing.
Thoughts?
Use a StopWatch to accurately measure time; and use a Timer to periodically fire a UI update, displaying the time measured by the StopWatch. For UI, you don't need 1 ms resolution (The screen update time is likely to be larger than 1 ms, and, the human eye won't be able to perceive updates that fast anyways).
Try having updates each 40 - 100 ms, I think that will be adequate.
Use another Timer that fires events every 10th of a second or so and polls for the Stopwatch value. It won't be nearly as accurate as the Stopwatch since there will be a lag but humans can't really react to anything faster than a 10th of a second.
Use the System.Timers.Stopwatch class, and check if high resolution is available by checking the field IsHighResolution (System.Timers.Stopwatch.IsHighResolution == true).
Then, whenever you need something fired, fire it through another timer at the lowest interval possible, which checks the value of your Stopwatch. Though this won't be perfect (you don't even need close to perfect), it'll work.
I'm programming a Netduino board using the .NET Micro Framework 4.1 and want to get a higher time resolution than milliseconds. This is because I'm attempting to dim an LED by blinking it really fast.
The issue is that the sample code uses Thread.Sleep(..) which takes a number of milliseconds.
Sample code from http://netduino.com/projects/ showing the issue in question:
OutputPort ledOnboard = new OutputPort(Pins.ONBOARD_LED, false);
while (true)
{
ledOnboard.Write(true);
Thread.Sleep(1); // << PROBLEM: Can only get as low as 1 millisecond
Even if there's another way to accomplish dimming by not using a greater time resolution, I'm game.
This doesn't answer your question about getting a better time resolution, but it does solve your problem with changing the brightness on an LED. You should be using the PWM module for the Netduino.
Netduino Basics: Using Pulse Width Modulation (PWM) is a great article on how to use it.
I have had a similar problem in the past and used the following method to time in the microsecond range. The first line determines how many ticks are in a millisecond (its been a while since I used this, but I think 1 tick was 10 microseconds). The second line gets the amount of time the system has been on (in ticks). I hope this helps.
public const Int64 ticks_per_millisecond = System.TimeSpan.TicksPerMillisecond;
public static long GetCurrentTimeInTicks()
{
return Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks;
}
You can use a timer to raise an event instead of using sleep.
The Interval property on a timer is a double so you can have less than a millisecond on it.
http://msdn.microsoft.com/en-us/library/0tcs6ww8(v=VS.90).aspx
In his comment to Seidleroni's answer BrainSlugs83 suggests "sit in a busy loop and wait for the desired number of ticks to elapse. See the function I added in the edit". But I cannot see the function added to the edit. I assume it would be something like this:
using System;
using Microsoft.SPOT.Hardware;
private static long _TicksPerMicroSecond = TimeSpan.TicksPerMillisecond/1000;
private void Wait(long microseconds)
{
var then = Utility.GetMachineTime().Ticks;
var ticksToWait = microseconds * _TicksPerNanoSecond;
while (true)
{
var now = Utility.GetMachineTime().Ticks;
if ((now - then) > ticksToWait) break;
}
}
A point that you might not be thinking about is that your code is relying on the .NET System namespace, which is based on the real time clock in your PC. Notice that the answers rely on the timer in the device.
Moving forward, I would suggest that you take a moment to qualify the source of the information you are using in your code -- is it .NET proper (Which is fundamentally based on your PC), or the device the code is running on (Which will have a namespace other than System, for example)?
PWM is a good way to control DC current artificially (by varying the pulse width), but varying the PWM frequency will still be a function of time at the end of the day.
Rather than use delays....like Sleep....you might want to spawn a thread and have it manage the brightness. Using Sleep is still basically a straight line procedural method and your code will only be able to do this one thing if you use a single thread.