Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Sleep() and Application.ProcessMessages()?



Permlink Replies: 5 - Last Post: Aug 3, 2016 7:02 AM Last Post By: Alex Belo
Bo Berglund

Posts: 757
Registered: 10/23/02
Sleep() and Application.ProcessMessages()?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 1, 2016 1:23 AM
I never really understood the way these functions work except I have
used them in various places like delays and such...

Now I would like to know if I can use Sleep(1) in a loop waiting for a
change in a state variable or similar, which is modified by an event
function (for example a socket or comm port or similar)?

Something like:
var
  T1: Cardinal;
begin
  T1 := GetTickCount;
  while (GetTickCount - T1) < 1000 do //Timeout 1 second
  begin
    if FConnected then break;
    Sleep(1); //To limit CPU usage in the loop
    Application.ProcessMessages; // Is this needed???
  end;
  Result := FConnected;
end;


Do I need the Application.ProcessMessages call to see the change in
FConnected, which is set in an OnConnected event in the other object?
The problem with Application is that it needs bringing in the Forms
unit which bloats the size of the program a lot for a command line
program use.

--

Bo Berglund
Sweden & Texas
now using XanaNews 1.20-0cfde51
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Sleep() and Application.ProcessMessages()?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 1, 2016 10:51 AM   in response to: Bo Berglund in response to: Bo Berglund
Bo wrote:

Now I would like to know if I can use Sleep(1) in a loop waiting for a
change in a state variable or similar, which is modified by an event
function (for example a socket or comm port or similar)?

Is the event being fired in a different thread, or the same thread that is
running the loop? It makes a difference, since the waiting thread is blocked
in the loop.

Do I need the Application.ProcessMessages call to see the change in
FConnected, which is set in an OnConnected event in the other object?

Only if:

1. OnConnected is a message-based event that goes through the thread's message
queue.

2. OnConnected is fired in the same thread that is running the loop.

Otherwise no, calling ProcessMessages() will not have the desired effect.

The problem with Application is that it needs bringing in the Forms
unit which bloats the size of the program a lot for a command line
program use.

Command-line apps don't usually have a message queue or windows, though they
can.

And yes, the Forms unit adds a lot of bloat to an app. It is for exactly
that reason that Indy's TIdAntiFreeze component (which uses Application.ProcessMessages())
is not part of the main library, and will not link to the Forms unit unless
TIdAntiFreeze is actually used in your project.

--
Remy Lebeau (TeamB)
Peter Below

Posts: 1,227
Registered: 12/16/99
Re: Sleep() and Application.ProcessMessages()?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 1, 2016 11:04 AM   in response to: Bo Berglund in response to: Bo Berglund
Bo Berglund wrote:

I never really understood the way these functions work except I have
used them in various places like delays and such...

Now I would like to know if I can use Sleep(1) in a loop waiting for a
change in a state variable or similar, which is modified by an event
function (for example a socket or comm port or similar)?

That will not work if the event is fired in the context of the same
thread that does the wait.

If you are not building a program with an interactive UI you should not
use event-based programming. Instead directly wait for the input to
arrive. For program without UI it does not matter if you block the main
thread this way, unless (and that is a very important caveat) said main
thread does actually create a window. A thread owning a window handle
must have a working message loop, or it may block the operation of
other programs. A typical case here is a program that tries to
establish a OLE or DDE connection by broadcasting a message to all
top-level windows.


Something like:
{code}
var
T1: Cardinal;
begin
T1 := GetTickCount;
while (GetTickCount - T1) < 1000 do //Timeout 1 second
begin
if FConnected then break;
Sleep(1); //To limit CPU usage in the loop
Application.ProcessMessages; // Is this needed???

Argh, horrible construction <g>.

Do I need the Application.ProcessMessages call to see the change in
FConnected, which is set in an OnConnected event in the other object?

Depends on the way said component implements the event. If the
component actually does the communication itself in a secondary thread
it will typically be designed to fire its events in the context of the
main thread through the use of TTHread.Synchronize. Many comm
components designed for use in VCL forms applications work this way.

To handle Synchronize calls in an application that does not have a
message loop in the main thread you write a loop that calls
CheckSynchronize (Classes unit) instead of ProcessMessages.

It is also possible to have the main thread actually wait for a
Sychronize call to be made from a secondary thread. for this purpose
the Classes unit has a public variable named SyncEvent (a API event
handle) on which you can wait using one of the API Wait functions. If
the wait returns because the event handle was signalled call
CheckSynchronize to execute the queued call.

--
Peter Below
TeamB

Alex Belo

Posts: 626
Registered: 10/8/06
Re: Sleep() and Application.ProcessMessages()?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 2, 2016 8:55 AM   in response to: Bo Berglund in response to: Bo Berglund
Bo Berglund wrote:

Do I need the Application.ProcessMessages

ProcessMessages is (dirty usually) way to process pending messages in
the message queue of the main thread.

If you expect that

1) some secondary thread will put a message in the queue
2) processing of this message will set needed flag ("FConnected")

than you can use this technic. But note: the queue will contain also
many other messages (clicks on buttons in UI, for example) and
processing of these messages before completion of your current
subroutine (especially if this subroutine is also processor of some
message) may result in strange effects.

--
Alex
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Sleep() and Application.ProcessMessages()?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 2, 2016 10:44 AM   in response to: Alex Belo in response to: Alex Belo
Alex wrote:

ProcessMessages is (dirty usually) way to process pending messages
in the message queue of the main thread.

More accurately, Application.ProcessMessages() processes pending messages
in the message queue of the calling thread. If it is called in a worker
thread (which is not advisable, but technically possible, and some people
actually do it), the main thread's message queue is not touched.

If you expect that

1) some secondary thread will put a message in the queue 2) processing
of this message will set needed flag ("FConnected")

than you can use this technic.

Just know that calling ProcessMessages() can cause unexpected reentry problems
if you are not careful. Most people who use Application.ProcessMessages()
do not understand this and thus do not write reentrant-safe code.

If the desired event is triggered by a specific message, it would be safer
to call PeekMessage() and DispatchMessage() directly instead:

var
  T1: Cardinal;
  Msg: TMsg
begin
  T1 := GetTickCount;
  while (not FConnected) and ((GetTickCount - T1) < 1000) do //Timeout 1 
second
  begin
    if PeekMessage(Msg, 0, TheEventMsgID, TheEventMsgID, PM_REMOVE) then
      DispatchMessage(Msg)
    else
      Sleep(1); //To limit CPU usage in the loop
  end;
  Result := FConnected;
end;


--
Remy Lebeau (TeamB)
Alex Belo

Posts: 626
Registered: 10/8/06
Re: Sleep() and Application.ProcessMessages()?
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 3, 2016 7:02 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:

ProcessMessages is (dirty usually) way to process pending messages
in the message queue of the main thread.

More accurately, Application.ProcessMessages() processes pending
messages in the message queue of the calling thread. If it is called
in a worker thread (which is not advisable, but technically possible,
and some people actually do it)

Hmm, I never thought about this possibility.
But I'll never use it, I believe. :)

Just know that calling ProcessMessages() can cause unexpected reentry
problems if you are not careful. Most people who use
Application.ProcessMessages() do not understand this and thus do not
write reentrant-safe code.

Yes, exactly.

If the desired event is triggered by a specific message, it would be
safer to call PeekMessage() and DispatchMessage() directly instead

OK, thank you for information.

--
Alex
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02