2
votes

I have a message queue based on a thread that processes messages being thrown at it. As some activities in the thread may be VCL commands they are performed in Synchronize. As soon Synchronize is called the thread hangs. Sample code:

TMessageQ = class (TThread)
...
procedure TMessageQ.do_msg;
begin
   case CurrentMessage.Command of
      cQSize:  if Assigned (OnSize)  then OnSize  (CurrentMessage);
      cQReady: if Assigned (OnReady) then OnReady (CurrentMessage);
   end; // case
end; // do_msg /

procedure TMessageQ.doTask (Sender: TObject);
begin
   while FQ.Count > 0 do
   begin
      FSection.Enter;
      try
         CurrentMessage := FQ.Dequeue;
      finally
         FSection.Leave;
      end; // try..finally
      Synchronize (do_msg);
   end; // while
end; // doTask //

No statement in do_msg is ever being processed. Does somebody know what I am doing wrong?

1
What is happening in the Main thread? Synchronize needs the MessageLoop. If the main thread is waiting for this one then it would figure. - Henk Holterman
+1 for Hank - identifying the #1 reason for dead Delphi apps - TThread.Synchronize and, (probably), TThread.WaitFor(). Like Hank says, whatever you are doing in your GUI thread, stop doing it, exit the event-handler and resume processing messages. If, at this stage, the phrase 'Application.ProcessMessages' is going through your brain - purge it :) - Martin James
I am afraid you are right (see comemnt below). And thank you for warning against Application.ProcessMessages :-). I'll test this in the evening. - Arnold
yes, you were right. See my comment at remy's answer. - Arnold

1 Answers

4
votes

TThread.Synchronize() blocks until the main thread processes the request. The main thread requires an active message loop in order to process requests (unless you manually call Application.ProcessMessages() or CheckSynchronize() periodically). If your thread's main work is always being invoked by TThread.Synchronize(), there is no point in using a thread at all. You could just use a timer or custom window message in the main thread instead and take out all of the unnecessary complexity.