2013-05-15 37 views
3

我知道你需要synchronize (yourprocedure)来设置例如一个标签的文本。 但是如何:何时需要在TThread中同步?

  1. 读取标签的文本。
  2. 切换/设置标签的启用属性。
  3. 呼叫其他标签程序/功能(例如onclick事件)。

当我需要使用synchronize时,有一个简单的规则可以知道/记住吗?

PS .:是否与PostMessage/SendMessage同步?

回答

9

简单的经验法则:任何访问VCL UI组件需要同步。这包括读取和写入UI控件属性。 Win32用户界面,最着名的对话框如MessageBox()TaskDialog(),可以直接在工作线程中使用,无需同步。

TThread.Synchronize()SendMessage()类似(实际上,它曾在Delphi 5及更早版本的内部使用SendMessage()实施)。 TThread.Queue()类似于PostMessage()

+0

非常感谢。然后我真的需要做很多程序/功能来同步。 –

3

每次访问VCL UI组件时,都需要实现某种类型的线程安全措施。通常情况下,当您访问存在或将被另一个线程访问的变量或过程时也是如此。但是,您不需要需要以在所有这些情况下使用Synchronize方法。还有其他工具可供您使用,Synchronize并不总是您最佳的解决方案。

在执行传递给它的过程时,同步阻塞主线程和调用线程,因此过度使用会降低多线程的好处。同步可能是最常用于更新用户界面的,但如果您发现必须频繁使用它,那么检查并查看是否可以重构代码可能不是一个坏主意。 I.E.你真的需要从你的线程中读取标签吗?你可以在启动线程之前阅读标签并将它传递给线程的构造函数吗?你可以在线程的OnTerminate事件处理程序中处理这些任务吗?

+0

不幸。不需要,我需要在运行线程时偶尔进行检查。我认为,只要没有其他线程试图设置/写入地址空间,读取值/属性就不应该成为问题。但它必须谨慎处理。 –

+1

你的措辞是不幸的。调用线程肯定是阻塞的,但主线程肯定不是 - 如果它是如何执行通过的过程呢? – mghie

+1

主线程在执行传递的过程时被阻塞......因为它不响应事件或执行任何其他任务。我相信,为了找到讨论语义的理由,我的发言的意义对于没有阅读它的人来说是相当清楚的。 – Aaron