userbb
userbb

Reputation: 1874

ProcessMessages and use of application

I need to know if use of ProcessMessages that allow me to use entire application is legal.

Pseudo code:

Main thread button call - search.

procedure ButtonOnClick;
begin
    var1 = ExecuteSearch();
end;    

function ExecuteSearch:Something;
begin
 thread.StartThread;
 while thread.Finished do
 Application.ProcessMessages;
 result := something;
end;

When I use this construction I can click other parts of my software and use it. But I don't know how this works. And if its safe.

Upvotes: 1

Views: 2220

Answers (2)

David Heffernan
David Heffernan

Reputation: 612954

Whilst this can be made safe, you are playing with fire. You run the risk of re-entrancy. You have to make sure that the user cannot press the button again. I trust you have disabled it whilst the search is running. You must make sure that it is disabled before you first call ProcessMessages.

My advice would always be to avoid using ProcessMessages. Better would be to start the thread and arrange for it to notify the main thread when it is done. Of course, you still need to disable the button whilst the thread is running.

However, if you really must use ProcessMessages don't do it with a busy loop like this. There's not much point using an entire processor to wait for a long running search operation to complete. Use a more intelligent blocking loop like this:

while MsgWaitForMultipleObjects(1, Thread.Handle, False, 
    INFINITE, QS_ALLEVENTS)=WAIT_OBJECT_0+1 do
  Application.ProcessMessages;

The MsgWaitForMultipleObjects function will block until either:

  1. A message is placed on the queue, or
  2. The thread is signaled. The thread is signaled when it is complete.

The loop terminates when the thread is signaled, but also processes any queued messages.

Upvotes: 4

Stijn Sanders
Stijn Sanders

Reputation: 36840

Though the code is safe, what you could also do is use the OnTerminate event on the thread you're starting. This way you let Delphi control how to post back from the background thread to the main thread. Internally it uses the thread's Synchronize method, which you can use yourself to let the thread post intermediate progress information to the main thread.

Upvotes: 2

Related Questions