混乱的线程同步问题

时间:2010-01-19 01:44:46

标签: delphi multithreading synchronize

当我今天阅读Zarko Gajic的文章时,这让我感到困惑:

多线程Delphi数据库查询

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

Sourecode: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更新相关。据我所知,这些操作应该是使用线程同步,并由主线程执行。我的知识有缺陷吗?

2 个答案:

答案 0 :(得分:18)

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

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

答案 1 :(得分:0)

事实上。也许样本没有问题,因为在线程执行时没有UI更改。但UI事物总是必须在UI线程内发生。

我在sync'ed和not sync'ed指令之间看到的唯一区别是:

  • not sync'ed不是no-params方法所以程序会更难写:)
  • sync'ed方法正在更新一个不是TControl的TLabel(如果我记得我的Delphi天),所以它直接使用canvas ...

但无论如何:UI被单个线程触及。总是。一旦我想在一个线程内更新一个TTreeBox(没有参与派,也没有交叉更新,只是一个单独的线程),这是一个非常糟糕的事情(随机错误)......