Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Timer Question? 5

Status
Not open for further replies.

eric0524

Programmer
Oct 16, 2012
10
0
0
US
I am using a timer on my form, set to an interval of 120000 so it will get data from the National Treasury every two minutes.

Question: How can I show how much time is left before the timers, timer event fires? I was thinking about using a second timer that checks timer1 every second. My problem with that is that I can not see where it shows how many milliseconds are left before the timer1 fires?

I know once I can get the time that is left before the timer fires and just stick it in a
thisform.lblTimeLeftToFire.caption = {time left to fire}

I know somebody has had to do this before, it seems like it would be common for something using a timer.

I know I can create a property and store the time that it started then bounce off that but it there a way to do it right off the timer?
-E
 
The timer itself has no way of telling you how much time remains before it fires. So, you're right that you will need a second timer.

At the point at which you enable the first timer (that is, at the start of the two-minute period), store the current datetime in a variable. Then, in the Timer event of the second timer, subtract the contents of that variable from the current datetime. That will tell you how many seconds have elapsed since you started the first timer. From that, you can work out how many seconds remain until the first timer fires.

Hope this makes sense.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
There is no such thing as a counter you could query. A solution would be to introduce your own countdown property, lower the interval and in the timer code count down the countdown, only executing the main code, if the countdown is 0:

So add a property named "Countdown", set it 120, set interval 1000, and the first thing you do in Timer Event is:
Code:
This.Countdown = This.Countdown-1
If This.Countdown<=0
   * ... do stuff after 120 seconds
   This.Countdown = 120 && reset Countdown to 120 seconds
Endif

Bye, Olaf.
 
Obviously, additional to decrementing the countdown property internally, to notify the user of the remaining time, you could bind a textbox to that Timer.Countdown property to display the countdown, or SET MESSAGE inside the timer or whatever suits you best.

Bye, Olaf.
 
I would do it the other way, use one timer with an interval of a second let it fire an event that updates a countdown and start that at 120...
when it reaches zero, let the routine get the data from the National Treasury.

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.
 
Sure there is ... subclass the timer (to mytimer) and:

(1) Add a property called seconds
(2) On the init event, add the code: this.seconds = SECONDS()
(3) On the Timer event add the code: this.seconds = SECONDS()
(4) Add a custom method called mth_get_remaining(), and add the code:

Code:
RETURN (this.Interval / 1000.0) - (SECONDS() - this.seconds)

This will allow you at any time to call mytimer.mth_get_remaining and obtain the seconds remaining before firing.

To obtain the remaining time periodically, use a second timer on the form or parent class.

Best regards,
Rick C. Hodgin
 
Rick,

One small improvement to your idea: use DATETIME() rather than SECONDS(). That way it won't fail if the application runs overnight (that is, past midnight).

I know I'm nit-picking, but these things do happen.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
Thanks Rick, That's the ticket. I don't know how to close a post but I got my answer now.

 
Mike,

If I were implementing this for a general purpose class that really was mission critical, I would probably do both. But, I would only use the datetime comparison as a flag to see if it's actually gone across midnight. If it has crossed midnight, compute the seconds up to midnight, and the seconds since, otherwise just use the seconds calculation as above, that way I'm always returning fractional seconds.

And in full truth, were I doing this for any of my real projects, I would use a custom DLL call to implement the high-resolution timer that will not wrap (64-bit timer calls QueryPerformanceCounter() and QueryPerformanceFrequency()). I already have this method coded actually. Is accurate well beyond ms resolutions, but hardly ever truly necessary. Still, is very fast as most of these function calls on modern CPUs relate directly to internal CPU registers which are auto-incremented at their clock frequency.

Best regards,
Rick C. Hodgin
 
Well, you can use the high performance counters directly in VFP without an additional DLL via DECLARE. Craig S. Boyd showed that here already 2005: thread184-1086055. See
Just watch out the warnings of the MSDN reference in the Remark of [URL unfurl="true"]http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx[/url]
"On a multiprocessor computer, it should not matter which processor is called. However, you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL)."
That means in today's multi core systems you can't rely on that function to return counts from the same timer every time, though VFP only runs in one thread on one cpu anyway.

Also in [URL unfurl="true"]http://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx[/url] you can read: "The high frequency counter need not be tied to the CPU frequency at all. It will only resemble the CPU frequency is the system actually uses the TSC (TimeStampCounter) underneath."

I remember I've had a discussion about timing for timing and synching this year in some forum thread (maybe elsewhere) and found a good reference of someone doing a video application, that needs to synch on very different old and new systems, and it's developer found some timer to best rely on. I think it was the system/BIOS time anyway, and not some high performance counter.

Last not least:

The solution with the internal countdown proposed by me and Griff doesn't depend on time not crossing midnight. It can also give you fractional seconds, if you lower the interval and higher the countdown correspondingly. What is more influencing the overall runtime behaviour then is, that the VFP timer isn't precise. Especially if you go to intervals below 50ms, so perhaps go for Interval = 100 and a countdown from 1200 for 120 seconds, and you can determine the rest time in precision of 0.1 seconds. That should be quite sufficient. An advantage of such a countdown property is, you can shorten the current wait time, simply by setting the countdown property to 0 or 1, so the next timer event would make the Treasury query. That way you can also synchronize the VFP timer to occur at eg all odd minutes, by adjusting the countdown once in a while, eg take the current time after each query made into account and compute the countdown to the next even as 120 seconds minus the number of seconds, that passed, during making the query.

Bye, Olaf.
 
Olaf said:
Well, you can use the high performance counters directly in VFP without an additional DLL via DECLARE.

True, but I don't use DLLs just for one function. They are incorporated into a vast array of wide-sweeping and interconnected functions. And, I directly incorporate functions which make it far easier to utilize the high performance counter with something that makes more sense in source code:

Code:
lcStart = SPACE(8)
utils_dll_get_high_resolution_timer(@lcStart8)
* Do my workload here
* Get fractional seconds in 32-bit floating point
lfSeconds = utils_get_f32_seconds_on_high_resolution_timer(@lcStart8)

The warning given by Microsoft is on the order of a slight variance in return values at any given instant. On more modern CPUs, even with clock speed throttling, and especially over the long term (microseconds and greater) the values will be (more or less) in sync, possibly a few ticks off. If you are looking at resolutions near its clock speed it can fail if a task switch occurs during tight code execution and the thread resumes on another core. For anything on the order of microseconds or greater, you'll never see it.

Best regards,
Rick C. Hodgin
 
Olaf said:
I think it was the system/BIOS time anyway, and not some high performance counter.

The system/BIOS timer operates on a 16-bit countdown using a fixed frequency of 1.193182 MHz divided by programmable values which allow it to fire between 18.2 times per second and its maximum (a somewhat machine-dependent value as there is some overhead in acknowledging and processing the timer event itself, even at the chipset level).

This programmable interrupt timer (PIT) frequency is accurate to within a couple of seconds per day however, and more importantly is accurate enough to easily fire at or around 100,000 times per second or less for user-apps, making it ideal for digital sampling and syncing.

However, it is not reliable for general purpose extremely high resolution timing operations (microseconds or greater) outside of core OS functions because the overhead of scheduling messages to the indicated threads, task switching, and resuming.

It gets very complex at these levels. If such high resolutions are truly required, it's best to write a core kernel driver which handles the timing events for you, and then you use an API in a separate thread to query its computed values.

Best regards,
Rick C. Hodgin
 
>For anything on the order of microseconds or greater, you'll never see it.

I believe that blindly. On the other hand, using HPC (high performance counters) to measure from the last timer start point until 120 seconds passed, that means a lot of changes could happen. The frequency throttling alone makes the counter quite unstable for measuring time. You would need to know how many of the ticks the counter increased from start time where incremented in what frequency to get the integral time elapsed.

So HPC can be thought of as stable working at a certain CPU and frequency in short term intervals.

Something counting at a stable frequency and accumulating counts in always the same register/memory address is better for long term time measurement.

So you can't have the highest precision/resolution over a long period of time and vice vera can't measure longer time periods with a very high precision. Correct?

Bye, Olaf.
 
Olaf said:
The frequency throttling alone makes the counter quite unstable for measuring time.

IIRC, this was true on early implementations, but corrected on later ones.

The clock signal is distributed throughout the core at a continuous rate (notably slower than the actual clock frequency the CPU runs at internally, as it uses a multiplier to take the slower signal and generate the interim pulses).

The only thing that changes for CPU throttling is the multiplier used internally, and that on the periphery (on-die communication with other cores, external links to chipset, etc.). However, the clock signal coming onto the die is constant, and the logic involving the counter (in later implementations) remains constant as well. As such, it is suitable for measuring time (once calibrated as no two CPUs clock at exactly the same rate).

The typical solution is to sample the frequency counter over a period of time from another known timer source, such as the standard PIT. Once determined, the relationship can be assumed and is at least as accurate as the ~2 seconds per day the PIT is.

Best regards,
Rick C. Hodgin
 
Thanks, Rick, for the insight.

I havent thought that there would still be some constant frequency main oscillator and other frequencies are derived by multiplicators.

Bye, Olaf.
 
There's a CPU Multiplier article on Wikipedia describing it. And here's an interesting Yale article that describes the scenario a few years ago. It's only changed in implementation, width and breadth since then. The concept remains the same.

Best regards,
Rick C. Hodgin
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top