【问题标题】:Synchronize appears to hang thread同步似乎挂起线程
【发布时间】:2012-04-26 20:46:23
【问题描述】:

我有一个基于线程的消息队列,该线程处理抛出的消息。由于线程中的某些活动可能是 VCL 命令,因此它们在同步中执行。只要调用同步,线程就会挂起。示例代码:

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 //

do_msg 中没有任何语句被处理。有人知道我做错了什么吗?

【问题讨论】:

  • 主线程发生了什么?同步需要 MessageLoop。如果主线程正在等待这个,那么它就会出现。
  • Hank +1 - 确定 Delphi 应用程序死机的第一大原因 - TThread.Synchronize 和(可能)TThread.WaitFor()。就像 Hank 所说,无论您在 GUI 线程中做什么,都停止执行,退出事件处理程序并继续处理消息。如果在这个阶段,“Application.ProcessMessages”这个短语正在通过你的大脑 - 清除它:)
  • 恐怕你是对的(见下面的评论)。并感谢您对 Application.ProcessMessages 的警告:-)。我会在晚上测试这个。
  • 是的,你是对的。在 remy 的回答中查看我的评论。

标签: multithreading delphi delphi-xe


【解决方案1】:

TThread.Synchronize() 阻塞,直到主线程处理请求。主线程需要一个活动的消息循环来处理请求(除非您定期手动调用Application.ProcessMessages()CheckSynchronize())。如果你的线程的主要工作总是被TThread.Synchronize() 调用,那么使用线程根本没有意义。您可以只在主线程中使用计时器或自定义窗口消息,并消除所有不必要的复杂性。

【讨论】:

  • 恐怕就这么简单,我的主线继续。我会检查一下然后回来。
  • 你(以及 Henk 和 Martin)是对的。我使用主线程作为一种计时器来确定某个任务持续了多长时间。我在这里使用一个线程,因为我有两个不同的进程。在一个过程中发生了一些事情,另一个(异步)处理结果。在 stackoverflow.com/questions/9033860/… 中,建议使用两个线程来分离 CPU 密集型任务和 CPU 密集型任务。在这种情况下,线程更复杂,但我不需要考虑何时处理消息。只要您保持简单,线程有时会简化事情。
猜你喜欢
  • 1970-01-01
  • 2017-11-03
  • 2015-06-19
  • 1970-01-01
  • 1970-01-01
  • 2016-05-15
  • 1970-01-01
  • 2021-06-02
  • 2012-08-08
相关资源
最近更新 更多