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;
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.