PDA

View Full Version : Solved: Timer event = 100% CPU Usage



wadiohead
08-05-2005, 06:48 AM
I don't understand this at all, every time I use this timer procedure, it shoots up to 100% CPU Usage... even if I take pretty much EVERYTHING out of the code except the timer.


With Me
Start = Timer
Do While Timer < Start + CountDownTimer

counter = Format(CountDownTimer - (Timer - Start), "#")
DoEvents
With .lblSecondsCounter
If .Caption <> counter Then

If .Caption = "10" Then
.ForeColor = 255
Me.btnCancelAutorun.ForeColor = 255
Me.lblSeconds.ForeColor = 255
End If
pctcompleted = (Timer - Start) / CountDownTimer
UpdateProgress (pctcompleted)
.Caption = counter
End If
End With

If CancelAutoRun = True Then
RunAutomaticScript = False
.btnGenerateTable.Visible = True
.btnUpdateProdDB.Visible = True
GoTo EndGame
End If
Loop
End With
RunAutomaticScript = True

Notes:
CancelAutoRun is set to true by a button click.
UpdateProgress works with a progress bar. Disabling it does not effect CPU usage.
Endgame just does some simple exit procedure-type stuff.

Any advice would be appreciated... I'm just scratching my head here.

David

wadiohead
08-05-2005, 06:49 AM
Oh: Access 2003. And this is called from a OnLoad form procedure. Form is non-modal.

wadiohead
08-05-2005, 09:13 AM
Feel stupid that I solved my own stupid problem. The sleep method solves this:



Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)



Plus:

adding Sleep(100) into the loop. Causes the macro to pause execution, so as to avoid hogging all the resources for a loop that's effectively doing nothing.

xCav8r
08-08-2005, 08:40 PM
An enhancement to this idea is to capture the start time of the loop and compare it to a threshold value to force a timeout. For example, if I'm automating the creation of files, and I need to move each created file to a specific directory to avoid overwriting, then I might measure the time I started my Do While to raise a custom error to avoid an infinite loop.

wadiohead
08-08-2005, 09:08 PM
That's true, but when you're only trying to wait for a user response for a specified amount of time, there's just a loop running over and over again. So even if I'm only waiting ten seconds (and doing nothing but waiting in a loop until either the user responds or the time has elapsed), if I don't use a sleep call, the CPU usage will shoot up to 100% because the VBA engine will hog all available resources to execute that empty loop. Or am I still missing something? (likely)

xCav8r
08-09-2005, 07:44 AM
Sorry, your situation got me off on a tangent. My comment was a general comment that applies more to this situation:

Do While Condition = False
DoEvents
Sleep 100
Loop


When you don't know that condition will always come true, but you want to give it some time (eg. waiting on some other process to output a file), you can add something like this:


datLoopStart = Now
Do While Condition = False
DoEvents
Sleep 100
if datediff("s",datLoopStart,Now)=30 then
fLoopFailed = True
Exit Do
end if
Loop

wadiohead
08-09-2005, 07:51 AM
Yep. I got you.

My code could have been more clear (could have, for example, included the EndGame reference). Is there any advantage to placing the Condition as the Do While Loop as you have it, versus putting the Timer as the Do While Loop as I have it?

Both check the condition and the time every loop cycle, right?

Anyway, thanks for the input.

xCav8r
08-09-2005, 07:59 AM
The example I suggested is looking for some other process to output a file, so in that case, the loop condition would be...


datLoopStart = Now
Do While MyFileExists= False
DoEvents
Sleep 100
If datediff("s",datLoopStart,Now)=30 Then
fLoopFailed = True
Exit Do
End if
Loop