【问题标题】:Confusion of thread synchronization problem混淆线程同步问题
【发布时间】:2011-01-06 15:02:06
【问题描述】:

今天读到 Zarko Gajic 的文章让我很困惑:

"多线程 Delphi 数据库查询"

文章网址:http://delphi.about.com/od/kbthread/a/query_threading.htm

源代码:http://delphi.about.com/library/weekly/code/adothreading.zip

有了“TCalcThread.Execute”程序的代码,为什么下面的代码不需要放在Synchronize()方法中运行?

Line 173:    ListBox.Clear;  
Line 179:    ListBox.Items.Insert(......);
Line 188:    ListBox.Items.Add('*---------*');
Line 195:    TicksLabel.Caption := 'Ticks: ' + IntToStr(ticks);

这些代码是操作 VCL 组件的,与 UI 更新有关。据我所知,这些操作应该使用线程同步,并由主线程执行。难道我的知识有缺陷?

【问题讨论】:

    标签: delphi multithreading synchronize


    【解决方案1】:

    这是一种罕见的情况,您可以从 Windows 为您执行线程同步这一事实中受益。原因是对于一个列表框,项目是使用带有特定控件消息的 SendMessage 来操作的。因此,每个 SendMessage 调用确保消息由创建控件的同一线程处理,特别是主线程。

    就像我说的,这是一种罕见的情况。它还会导致这三个调用中的每一个都发生线程切换,这会降低性能。最好使用 Synchronize 强制该代码块在它所属的主线程中运行。它还确保如果您开始使用内部不使用 SendMessage 的控件,您不会被咬。

    【讨论】:

      【解决方案2】:

      确实如此。也许示例没有问题,因为线程执行时没有 UI 更改。但是 UI 的事情总是必须发生在 UI 线程中。

      我看到的已同步指令和未同步指令之间的唯一区别是:

      • 未同步的不是无参数方法,因此程序将更难编写:)
      • 同步的方法正在更新一个不是 TControl 的 TLabel(如果我记得我的 Delphi 时代),所以它直接使用画布...

      但无论如何:UI 由单个线程接触。总是。一旦我想在一个线程中更新一个 TTreeBox(没有并行性也没有交叉更新,只是一个单独的线程),这是一件非常糟糕的事情(随机错误)......

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-14
        • 2021-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-14
        相关资源
        最近更新 更多