【问题标题】:PostThreadMessage: Create a message queuePostThreadMessage:创建消息队列
【发布时间】:2023-03-03 09:35:01
【问题描述】:

我有一个关于线程在其生命周期开始时缺少消息队列的问题。 MSDN解释

消息发布到的线程必须已经创建了消息队列,否则对 PostThreadMessage 的调用将失败。使用以下方法之一来处理这种情况:

(1) 调用 PostThreadMessage。如果失败,调用 Sleep 函数并再次调用 PostThreadMessage。重复直到 PostThreadMessage 成功。

(2) 创建一个事件对象,然后创建线程。在调用 PostThreadMessage 之前,使用 WaitForSingleObject 函数等待事件设置为信号状态。在将要发布消息的线程中,调用PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE) 强制系统创建消息队列。设置事件,表示线程已准备好接收发布的消息。

方法 (1) 解决了我的问题,第二次调用 PostThreadMethod() 在我的应用程序中总是成功。

但是,我想理解第二种方法,根本不理解“事件对象”(当然不是正常的 Delphi 事件?)“信号状态”和“设置事件指示”。

问题:有人可以将第 (2) 段翻译成简短的 Delphi 代码示例吗?

【问题讨论】:

  • 请注意,我删除了第二个问题,因为在此站点上,它一次是一个问题。更重要的是,第二个问题会违反“主要基于意见”的密切原因。
  • @David:好的,也许您可​​以简短地评论一下您认为是否有比 PostThreadMessage() 更好的线程间通信方法?我希望工作线程对管理线程说“开始”和“完成”,该管理线程从列表中添加和删除工作线程。
  • 您当然不想使用线程消息。因为如果您显示任何模态 UI,它们会迷路。使用仅消息窗口是处理消息的方法。至于这是否是解决您问题的正确方法,我不能说背景这么少。
  • 嗯...所有涉及的线程,即工作线程和管理线程根本没有 UI。我想,线程可能不会使用 VCL 吗?只有主线程有 UI。这是一个问题吗?它似乎可以与 TEvent 一起使用,并且它也可以与重复的第一个 PostMessage 一起使用。
  • 通常管理线程也是UI线程。如果这些线程中的任何一个都没有 UI,那么线程消息可能就可以了。

标签: multithreading delphi delphi-10.2-tokyo


【解决方案1】:

这些事件对象是同步对象,在 MSDN 中描述:Event Objects

该主题的底部是指向Using Event Objects 的链接,该链接提供了示例代码,展示了如何创建事件、设置事件、等待事件等。

简而言之,您使用以下功能:

  • CreateEvent 创建事件对象。
  • CloseHandle 销毁它。
  • SetEventResetEvent 设置和重置事件对象。
  • WaitForSingleObject 等待它发出信号。

您可以使用System.SyncObjs 单元中的TEvent 类来包装所有这些低级API 调用。那么流程会变成这样:

  • 创建一个TEvent 对象,例如Event,处于重置状态。
  • 创建您的工作线程,传入Event
  • 在管理器线程中调用Event.WaitFor,等待工作线程发出其消息队列存在的信号。
  • 当工作线程开始执行时(即在其Execute 方法的开始处),让它创建其消息队列,然后通过调用Event.SetEvent 设置事件。

【讨论】:

  • 谢谢。 SyncObjs.TEvent 它是。 -- TEVent 是否仅限于当前流程?如果同一应用程序的多个实例正在运行,它们会看到彼此的事件吗?为了避免这种情况,我是否必须使用实例唯一的 TEvent 名称?
  • 您可以命名事件,但我不认为 RTL 类包含该功能
  • TEvent 支持“名称”,它现在对我有用。我只是不知道这个名称是在实例间工作还是仅限于当前实例。
  • MSDN 上涵盖了对象命名,是的,它用于进程间同步。
  • 是的,没问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
  • 2016-11-07
  • 2010-09-11
  • 2013-10-01
相关资源
最近更新 更多