PostThreadMessage:创建一个消息队列

时间:2018-04-02 11:36:35

标签: multithreading delphi delphi-10.2-tokyo

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

  

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

     

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

     

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

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

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

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

1 个答案:

答案 0 :(得分:5)

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

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

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

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

您可以使用System.SyncObjs单元中的TEvent类来包装所有这些低级API调用。然后这个过程会变得如此:

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