Search code examples
multithreadingdelphisynchronize

I want to Thread and Form work together


I want to run my Thread then run application instruction. why run all after Sleep? I have a TQuery(it has many record and slow fetch) instead Sleep and when Open, Thread no run before Open TQuery. ShowMessage and Sleep are for test. What's solution?

  TCustomThread = class(TThread)
  public
    procedure Execute; override;
    procedure doProc;
  end;
.
.
.
procedure TCustomThread.Execute;
begin
  Synchronize(doProc);
end;

procedure TCustomThread.doProc;
begin
  ShowMessage('Thread');
end;
.
.
.
procedure TForm1.Button1Click(Sender: TObject);
var
  thrd : TCustomThread;
begin
  thrd := TCustomThread.Create(True);
  thrd.Resume;
  Sleep(3000);
  ShowMessage('Form');
end;

Solution

  • Button1Click is stopping the execution of the main thread for 3 seconds.

    During the sleep(3000) execution, no GDI message is processed, so the dialog boxes are NOT displayed immediately.

    In fact, TCustomThread.doProc works as expected, but the dialog box is not displayed until the GDI messages are processed.

    You have to change this method e.g. into:

    procedure TForm1.Button1Click(Sender: TObject);
    var
      thrd : TCustomThread;
      expectedEnd: TDateTime;
    begin
      thrd := TCustomThread.Create(True);
      thrd.Resume;
      expectedEnd := Now+(1/24/60/60*3); 
      repeat
        Sleep(50); // or any long process
        Application.ProcessMessages; // to be called to process the GDI messages
      until Now>=expectedEnd;
      ShowMessage('Form');
    end;
    

    In short: never use Sleep() in the main GDI thread, for extended period of time (more than some ms), otherwise your application won't be responsive any more. And Windows will complain for it and ask you to kill the application!

    So in your case, you have to call Application.ProcessMessages in your main thread when a long process is taken place (e.g. a TQuery), or run the query in a background thread (this is IMHO the preferred method), as we do e.g. for our Open Source mORMot framework on client side.