【问题标题】:When do I need synchronize in TThread?我什么时候需要在 Thread 中同步?
【发布时间】:2013-05-15 00:26:13
【问题描述】:

我知道你需要synchronize (yourprocedure) 来设置例如标签的文本。 但是呢:

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

当我需要使用synchronize 时,是否有一条容易知道/记住的规则?

PS.: 同步类似于 PostMessage/SendMessage 吗?

【问题讨论】:

    标签: multithreading delphi tthread


    【解决方案1】:

    简单的经验法则:ANYVCL UI 组件 的访问需要同步。这包括读取和写入 UI 控件属性。 Win32 UI,尤其是像 MessageBox()TaskDialog() 这样的对话框,可以直接在工作线程中使用而无需同步。

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

    【讨论】:

    • 非常感谢。那我真的需要做很多程序/函数来同步。
    【解决方案2】:

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

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

    【讨论】:

    • 不舒服。不,我在运行线程时需要不定期检查。我实际上认为只要没有其他线程尝试设置/写入地址空间,读取值/属性就不应该成为问题。但是必须谨慎处理。
    • 你的措辞很不幸。调用线程肯定被阻塞了,但主线程肯定没有——如果是,它怎么能执行传递的过程?
    • 主线程在执行传递的过程时被阻塞......就像它不响应事件或执行任何其他任务一样。我相信我的陈述的含义对于那些没有阅读它以寻找讨论语义的理由的人来说是相当清楚的。
    猜你喜欢
    • 2015-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 2018-02-25
    相关资源
    最近更新 更多