Unoffical empeg BBS

Quick Links: Empeg FAQ | RioCar.Org | Hijack | BigDisk Builder | jEmplode | emphatic
Repairs: Repairs

Topic Options
#173841 - 05/08/2003 10:49 Off-topic programming question
tfabris
carpal tunnel

Registered: 20/12/1999
Posts: 31601
Loc: Seattle, WA
This is about programming, but it's about VB programming instead of empeg programming. But since it's about the EmpegFace program I'm trying to get working properly, I think it's OK to post it here.

The question: How to get a proper "relax and let things go" loop written that doesn't appear to consume 99% CPU in Task Manager when it's idle.

The standard thing in VB is to put the DoEvents statement in your loop. This allows messages to get processed by other programs (and elsewhere in your own program) whenever needed, yet allows your loop to continue. This works fine, doesn't slow down other programs, and still leaves your program responsive within the loop.

Except that when your program is idle and looping, and nothing else is doing anything important on the system, then Task Manager shows your idle loop consuming 99 percent CPU time, instead of the system idle process doing it. This produces complaints from your users.

The other way around this is to re-architect your program so that it doesn't need the idle loop. For example, using a timer to do the idling. Let's assume for a moment that I can't do this for various reasons. I'm already using timers for some things and in this particular case I've got my reasons for not wanting to use a timer.

Googling for solutions gives me replacement idle loops which call the Windows API functions GetMessage or PeekMessage. These work, but there is a problem: When I use the PeekMessage alternatives, the result is exactly the same as DoEvents: Idle loops consume 99 percent CPU time (in fact I think this behavior is an indication that DoEvents really is just a PeekMessage loop under the hood). When I use the GetMessage alternative, my program sits there and locks up waiting for a message (since in my idle loop, I'm not getting any messages, and the GetMessage alternatives only perform an action when there is a message to get).

Anyone got any ideas, or can you point me to any example code variations that use GetMessage and/or PeekMessage in ways that are satisfactory?
_________________________
Tony Fabris

Top
#173842 - 05/08/2003 11:12 Re: Off-topic programming question [Re: tfabris]
JeffS
carpal tunnel

Registered: 14/01/2002
Posts: 2858
Loc: Atlanta, GA
I always do any idle looping with timers, for the specific reasons you've outlined. Since you'd like (or need) to do this in a different way, what is the purpose of the idle loop? Are you waiting for a signal? I haven't coded in VB before, but I assume that most of the API calls I have available in Delphi (and therefore techniques) will also be available to you.
_________________________
-Jeff
Rome did not create a great empire by having meetings; they did it by killing all those who opposed them.

Top
#173843 - 05/08/2003 11:16 Re: Off-topic programming question [Re: JeffS]
tfabris
carpal tunnel

Registered: 20/12/1999
Posts: 31601
Loc: Seattle, WA
The timers in VB have a lower limit to their resolution, and I'd like to be able to do the loop more frequently than they allow, yet still not consume all the CPU to do it.
_________________________
Tony Fabris

Top
#173844 - 05/08/2003 11:30 Re: Off-topic programming question [Re: tfabris]
tman
carpal tunnel

Registered: 24/12/2001
Posts: 5528
Is there no yield function?

There's a big article on MSDN here about PeekMessage/GetMessage

Top
#173845 - 05/08/2003 11:31 Re: Off-topic programming question [Re: tfabris]
JeffS
carpal tunnel

Registered: 14/01/2002
Posts: 2858
Loc: Atlanta, GA
Are you polling to try and respond to an external windows message, or is this something that you're generating internally (or are you not polling at all and I'm missing the point)?
_________________________
-Jeff
Rome did not create a great empire by having meetings; they did it by killing all those who opposed them.

Top
#173846 - 05/08/2003 11:42 Re: Off-topic programming question [Re: JeffS]
tfabris
carpal tunnel

Registered: 20/12/1999
Posts: 31601
Loc: Seattle, WA
(or are you not polling at all and I'm missing the point)?
I'm trying to find a way for the program to sit and wait for something to change that doesn't involve windows messages at all. The only reason I'm trying Peek/Get is because examples on the 'net said "hey, this is an alternative to a DoEvents idle loop".

/me heads off to look at the linked MSDN article.
_________________________
Tony Fabris

Top
#173847 - 05/08/2003 11:52 Re: Off-topic programming question [Re: tfabris]
JeffS
carpal tunnel

Registered: 14/01/2002
Posts: 2858
Loc: Atlanta, GA
I'm probably being unhelpful here, so ignore whatever doesn't make sense to your problem. However, in Delphi you can simply declare new message events and they get triggered whenever you do a "post message", no loop needed. Underneath it all (I know because I've looked) it's really just registering these events with windows when it creates the main application window. I can only assume that there's a way to do this in VB. This would allow you to respond when something changes through windows messaging.

The "atomic bomb" approach is that you could spawn a separate thread that does a CPU-friendly wait and then executes as soon as you trip it through with event. Of course then you have to take steps to ensure that you are synchronizing everything properly with the main thread so you don't start causing multi-threading issues. Probably too much for what you're wanting, and I'm not sure how hard multi-threading is to do in VB. However, it's very CPU friendly to do this in order to wait on something specific that either trips an event or you can cause to trip an event..
_________________________
-Jeff
Rome did not create a great empire by having meetings; they did it by killing all those who opposed them.

Top
#173848 - 05/08/2003 11:54 Re: Off-topic programming question [Re: JeffS]
tfabris
carpal tunnel

Registered: 20/12/1999
Posts: 31601
Loc: Seattle, WA
If it weren't such a pain to do multi-threading in VB, I'd definitely take that approach. In fact, the whole presence of this idle loop is a work-around to the fact that VB multithreading is a PITA.
_________________________
Tony Fabris

Top
#173849 - 05/08/2003 12:20 Re: Off-topic programming question [Re: tfabris]
tfabris
carpal tunnel

Registered: 20/12/1999
Posts: 31601
Loc: Seattle, WA
Hmm. I seem to have worked around it for now, and I'm going to see if this works out long term. For now, the answer to my original question is now an academic curiosity. The MSDN article sheds a lot of light on the subject, thanks for that link.
_________________________
Tony Fabris

Top
#173850 - 05/08/2003 12:21 Re: Off-topic programming question [Re: tfabris]
Roger
carpal tunnel

Registered: 18/01/2000
Posts: 5683
Loc: London, UK
I think this behavior is an indication that DoEvents really is just a PeekMessage loop under the hood

IIRC, it is.

What is it that you're waiting for? This might give us some clues about other ways to wait for it.
_________________________
-- roger

Top
#173851 - 05/08/2003 12:25 Re: Off-topic programming question [Re: Roger]
tfabris
carpal tunnel

Registered: 20/12/1999
Posts: 31601
Loc: Seattle, WA
I'm embarassed to say. It's a really kludgy work around to the lack of easy multithreading code in VB.

Anyway, like I said, I think it's working OK now and I no longer need the alternative to the idle loop.
_________________________
Tony Fabris

Top
#173852 - 05/08/2003 12:32 Re: Off-topic programming question [Re: tfabris]
JeffS
carpal tunnel

Registered: 14/01/2002
Posts: 2858
Loc: Atlanta, GA
Glad you found something that works. Just for the sake of posting what I've found, it seems you can handle windows messages in VB with AddressOf, which I believe would enable you to put whatever it is you're waiting for into the main message handler, if I understand everything correctly (which I may not, as I just skimmed the page). Then you wouldn't have to poll for anything and only respond when the event happens.
_________________________
-Jeff
Rome did not create a great empire by having meetings; they did it by killing all those who opposed them.

Top
#173853 - 05/08/2003 12:43 Re: Off-topic programming question [Re: JeffS]
tfabris
carpal tunnel

Registered: 20/12/1999
Posts: 31601
Loc: Seattle, WA
Ooo, that's neat. I'll hang onto that one for future reference.
_________________________
Tony Fabris

Top
#173854 - 05/08/2003 13:20 Re: Off-topic programming question [Re: tfabris]
DomoKun
journeyman

Registered: 14/03/2002
Posts: 94
Loc: Pennsylvania
The question: How to get a proper "relax and let things go" loop written that doesn't appear to consume 99% CPU in Task Manager when it's idle.
Use the API command Sleep together with Doevents.

Put this in a module:
Public Declare Sub Sleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)
Then you can make a loop like this:
Do
Sleep 1
DoEvents
Loop
This gives execution back to windows for 1 millisecond, then returns to your program to do a DoEvents command. Task manager will show your program as using 0% cpu.

Top
#173855 - 05/08/2003 15:21 Re: Off-topic programming question [Re: DomoKun]
tfabris
carpal tunnel

Registered: 20/12/1999
Posts: 31601
Loc: Seattle, WA
I could swear I tried this and for some reason it didn't work. Don't remember why, but I remember giving up on the Sleep API pretty quickly. If I have to go back to the loop method again, though, I'll make sure to try it exactly as you just showed. Perhaps I wasn't doing it exactly that way.
_________________________
Tony Fabris

Top