【问题标题】:TThread.Synchronize causing (near) deadlock in Delphi 2009 (worked in Delphi 7)Thread.Synchronized 在 Delphi 2009 中导致(接近)死锁(在 Delphi 7 中工作)
【发布时间】:2011-10-12 15:57:45
【问题描述】:

在 Delphi 2009 中,在 Delphi 7 中运行良好的同步函数执行速度非常慢,直到您将鼠标悬停在打开的表单上。摆动鼠标会导致程序进入某种鼠标空闲状态CheckSynchronize()CheckSynchronize() 在 Delphi 2009 中的调用频率似乎低于在 Delphi 7 中,但我们不知道为什么或在哪里。

放置此代码:

    procedure TMyForm.FormCreate(Sender : TObject)
       Classes.WakeMainThread := WakeMainThread;
    end;

    procedure TMyForm.WakeMainThread(Sender: TObject);
    begin 
      SendMessage(Application.MainForm.Handle, WM_NULL, 0, 0);
    end;

以正常速度加快速度。但是我得到:EAccessViolation in module rtl120.bpl 如果线程在模态应用程序中使用,则当线程死亡时(对于简单的对话框实用程序来说效果很好)。我猜 'Classes.WakeMainThread()' 的调用次数和 Delphi 7 中的一样多,但是将 WM_NULL 发送到 application.handle 并没有完成任何事情。我想是时候“踏踏实实”了。

【问题讨论】:

    标签: multithreading delphi delphi-7 delphi-2009


    【解决方案1】:

    Synchronize() 机制的内部结构在 D7 和 D2009 之间没有太大变化。当然,已经添加了新功能(异步排队、匿名方法等),但在主线程中运行代码的核心实现并没有改变。更有可能发生的是您的主线程代码中尚未显示的其他内容正在阻止主线程正确处理未决消息和Synchronize() 请求。

    【讨论】:

    • 我的编辑是否有助于回答问题?我们一直在研究调用 CheckSynchronize 函数的位置,并且只有当 wm_null 传递给活动表单时,才会以某种方式将其传递给应用程序和运行线程的表单之间存在脱节。这似乎已经发生了变化,可能与 MDI 窗口拥有和通知 MDI 子表单的方式有关,但我不知道从哪里开始在 VCL 中寻找它(或如何纠正它)。
    • CheckSynchronize() 在主线程上下文中调用 TThread.WaitFor() 时也会调用,并且每当主线程消息循环在处理完队列中的所有待处理消息后空闲时。跨度>
    • 嘿,我想你几年前可能有answered this already,抱歉挖了它。但是,这是同样的问题吗? (为了记录,他们正在共享 RTL bpl)
    【解决方案2】:

    TApplication.Create 正在从另一个 DLL 调用,因此它在该回调中唤醒了无效句柄或一些废话。

    您需要消除包含 [vcl.]controls.pas 的静态链接 DLL,因为 TApplication.Create 发生在该单元的某些初始化代码中。

    执行此操作后,同步将恢复往日的辉煌。

    不幸的是,您在一个版本的 Delphi 中所做的修复可能会因在另一个版本的 Delphi 中所做的更改而被撤销。因此,如果问题再次出现,请回到绘图板上。逐步执行初始化代码,特别是 system.pas 中的 initUnits 过程。它运行初始化代码并最终会碰到 vcl.controls.pas,您可以查看UnitInfo 记录以找出从哪个文件调用它。


    解决此问题的最佳方法是将delayed 与所有外部 dll(至少所有 Delphi VCL 外部 DLL)一起使用。

     function didntknowIusedcontrolsbutIdo() : Integer; external 'useful.dll' delayed;
    

    但这仅适用于 Delphi 2010 及更高版本。在您提出这个问题和最终找到令人满意的答案之间,您升级到 XE2 是一件好事。

    【讨论】:

      猜你喜欢
      • 2011-06-09
      • 2011-05-28
      • 2010-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-05
      • 1970-01-01
      相关资源
      最近更新 更多