我想将Thread和Form一起工作

时间:2014-04-20 14:29:00

标签: multithreading delphi synchronize

我想运行我的Thread然后运行应用程序指令。为什么在Sleep之后全部运行? 我有一个TQuery(它有很多记录和慢速提取)而不是Sleep,当Open时,Thread没有在Open TQuery之前运行。 ShowMessageSleep用于测试。 什么解决方案?

  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;

2 个答案:

答案 0 :(得分:0)

我理解你的问题是

  

为什么表单消息出现在线程消息之前?

简单地说,使用Synchonize意味着所有代码都在主线程上执行。这意味着第一个消息框必须等待第二个消息框完成。

那么,为什么首先显示表单消息框?从线程使用Synchronize方法来调用主线程上的代码。这个Synchronize方法告诉主线程有工作要做,然后阻塞直到主线程可以做到。

主线程在程序运行时忙于事件处理程序时不会启动此工作。因此,对Sleep的调用实际上会阻塞两个线程,因为两个线程都在主线程上等待。

因此,为了重新封顶,Synchronize方法会阻塞,直到主线程完成传递给Synchronize的过程中描述的工作。如果主线程忙,则Synchronize将阻塞,直到主线程完成其繁忙任务。


更广泛地查看您的问题,您将描述在主线程上发生的长时间运行的数据库任务。有根本问题。您不能在主线程上拥有这些任务。主线程专用于为GUI提供服务。这要求它始终具有响应能力并能够为其消息队列提供服务。将长时间运行的任务放在主线程上将破坏您的GUI。将这些任务放在远离主线程的工作线程上。

我怀疑您使用的是Synchronize,因为您已经意识到由于您的数据库代码,GUI没有响应。并且您可以使用线程来保持GUI响应。但这永远不会奏效。主线程必须及时处理消息。如果数据库代码不这样做,那么您无法从外部为消息队列提供服务。必须有合作。

这里的底线是长时间运行的任务必须远离主线程执行。

答案 1 :(得分:-1)

Button1Click停止执行主线程3秒钟。

sleep(3000)执行期间,没有处理GDI消息,因此不会立即显示对话框。

实际上,TCustomThread.doProc按预期工作,但在处理GDI消息之前不会显示该对话框。

您必须更改此方法,例如成:

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;

简而言之:永远不要在主GDI线程中使用Sleep()一段时间(超过几毫秒),否则你的应用程序将不再响应。 Windows会抱怨并要求你杀死该应用程序!

所以在你的情况下,你需要在进行长进程时调用主线程中的Application.ProcessMessages(例如TQuery),或者在后台线程中运行查询(这是恕我直言)首选方法),正如我们所做的那样我们的Open Source mORMot framework on client side