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 SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Timer stops occassionally

Status
Not open for further replies.

GriffMG

Programmer
Mar 4, 2002
6,288
1
38
FR
I have an app, running on about 20 machines, all day everyday, all under my control and
without any human intervention.

It uses a simple timer to countdown and then runs a process. When the process finishes
the countdown starts again from a preset figure.

Once is a blue moon, the timer stops mid count, if it is coming down from, say, 200 it stops
at 184 or 93 or another seemingly random point. No more processes get fired, no errors, definitely
not in the process and nothing obvious as to why. The timer is enabled, it was counting down and
it just stops. I have a button that fires the process and resets the clock, that still works,
I can hit the escape key to exit the app.

Any ideas ?

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Reading Daves thread gives some more ideas.

To summarize:
Look into Windows event logs, what happend at the time the timer got stuck. That's easier, if you update a display of current time in the timer, so you see the time it last worked.
Menu or other modal dialogs (messagebox) can make the timer stop working.
Have error handling and log errors, so you may also see a timewise coincidence,
Use other timers, eg bbcontrols.com cpptimer.fll - the site seems down, though.

Bye, Olaf.
 
You could use a second timer, that only has to work once and has a DO WHILE in its timer event:

First, have Sleep declared: [tt]Declare Integer Sleep In WIN32API Integer nMilliseconds[/tt]

Code:
THIS.ENABLED=.F.
Local ltNextReset
Do While .T.
   Thisform.Timer1.Reset()
   Thisform.Timer1.Enabled=.T.
   ltNextReset=DateTime()+300
   Do While DateTime()<ltNextReset
      Doevents Force
      Sleep(250)
   EndDo
EndDo

So this will never end and restart this separate timer. It still won't stop the whole app or system, as it normally will do the inner while loop doing DOEVENTS, which also includes timer events. Every 300 seconds it'll simply reset and enable the old timer. You might also do a MOUSE or anything, as suggested solution to kick the normal timer back working.

You need a timer for this, as you can't put it into Load, Init, Activate or anything on the form level, which would never finish.

You may also use this as your new overall timer.

Bye, Olaf.
 
I will put the time & date of last count on there - that might be useful.

A second timer probably won't help though - the other thread noted that two timers just stop
at the same point.

Thanks for the thought

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
I am not ignorant, I have read that another trial with a secondary timer didn't work, but this idea differs, otherwise I wouldn't have proposed it.

This second timer just runs once and never stops its Timer event. So it doesn't stop with the current timer.
Please read all I wrote already.

Bye, Olaf.
 
I thought that if one time fired an event the other timer would stop anyway...
Lemme check

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
You still havent comoprehended this additional timer just runs once at application start.
Its Timer event never stops, so it doesn't depend on the timer concept to work. It only needs to be a timer to not interrupt the main program flow.
It just depends on the timer event to happen once.

What do I do here, I have explained it already-

Bye, Olaf.
 
Olaf said:
Menu or other modal dialogs (messagebox) can make the timer stop working.

That certainly was the case in VFO 3.0, but it was fixed in later versions:

Hacker's Guid to Visual FoxPro said:
Timers fire when the menu is dropped down. They didn't in VFP 3.0. Timers fire in toolbars. Timers fire when a form is being dragged around. Timers fire when another application window is resized, or when Fox's window is resized. Timers fire when your application displays a message box. Awesome!

Mike





__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hi Olaf

Don't rush out to try and explain three different ways, I get what you are talking about, I just made a little test for to see
what happens, using a variant of your code.

Normally, if that is the right word, if you have two timers on one form and timer1 fires its event - then timer2 actually
stops firing, while the code for timer1 executes.

In your case you are running code from one timer - with a sleep in it and a doevents, which allows the other timer a few moments
every now and then to nip in and fire its event, and after 300 seconds it resets the other timer anyway (tickles it if you like)
so if it has stopped it will be restarted. It doesn't even matter if the tickling timer stops firing its event, in fact it has to stop
firing because on the first tick it runs a do while loop that precludes it from doing more.

In practise, using a simple form with two timers, the loop from the second timer (the do while .t. one) does let the event fire from the
first timer - and by putting a thisform.refresh and a setfocus on the text value of the countdown within the first timers event
I can see it working... so it has to be worth trying in the field.

Thank you - maybe that is a solution, it almost looks like multithreading when you watch the test form in play.

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Oh my god, I see the misunderstanding

I'm not proposing this code for both timers. This is just meant for a secondary timer.

Bye, Olaf.
 
Hi Olaf

I get that, and it does work in a test form.

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
OK, and now
You may also use this as your new overall timer.

Code:
THIS.ENABLED=.F.
Local ltNextClick
Do While .T.
   THISFORM.SCANFORREQUESTS.CLICK()
   ltNextClick=DateTime()+200
   Do While DateTime()<ltNextClick
      *update counter/labels, if you like
      Doevents Force
      Sleep(250)
   EndDo
EndDo

This way you only depend on a single Timer event once at startup. And you immediately see it working, if you do something visually showing in the inner Do While.

Bye, Olaf.

 
If you do it that way, you have essentially done away with the need for a timer and just made yourself a real-time event loop.

Looks pretty elegant to me.



Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
>you have essentially done away with the need for a timer.

Almost, you can't put this anywhere as PRG or form method and call it from anywhere, as it'll get stuck in the call stack and block everything else from executing, even though it has DOEVENTS in it.
So I am needing the event characteristic of the timer event, once. This timer event also is on the call stack, but it's not blocking anything, it's a separate entry with no caller, it's a root stack element itself.
So it's kind of a fork of program flow.

You may push this one step further and instead of using a timer do this as replacement for READ EVENTS. But then you'll need a form reference and it's not nicely extensible and breaks encapsulation.

The idea to use a while loop was already given in some articles and posts, but also seen as inelegant hack. Putting this in a timer just needing it's initial timer event puts away the sorrow it'll be blocking other code.

As a very similar concept you can sometimes do something once after a short wait time with a "run once" timer, which quits and releases itself after executing its code. That does not apply here, as the code needing to run is an infinite loop.

Bye, Olaf.
 
I made a test PRG and it does not really fork program flow as far as I thought, ie the timer still is interrupting current program flow, but you can have a form up and clicks run while this timer event never ends, so it actually only "interrupts" READ EVENTS. As it interrupts endless, it actually replaces READ EVENTS, ie the call stack typically has READ EVENTS, the timer code DOEVENTS FORCE line and some other code currently running on it. It's not as separate as a new thread would be.

It works good enough to see, whether the problem really are VFP timers. If your EXE still gets stuck at some point you'd have another hint on the problem. And if you never encounter problems again, fine.

Bye, Olaf.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top