PostMessage:保证交付?

在我的C ++应用程序中,我有一个后台线程可以完成一些工作,将结果放入一个堆分配的内存块中,然后调用PostMessage将结果传递给Main-Thread。

通常,当Window接收到消息时,它处理结果,然后在lParam指定的内存上执行delete

但是我担心窗口在处理消息和删除内存之前可能会退出。

PostMessage以某种方式保证目标窗口将有机会处理消息?
如果没有,有没有知道Window是否释放了内存的知名技术,或者后台线程是否需要负责删除?

PostMessage一定会放入接收窗口的消息队列中。 但是,不能保证窗户会在那里。 它可能已经被那个时代毁灭了。 确保消息的一种方法就是创建自己的隐藏窗口(COM通常使用这种技术)并将其发布到队列中。 这样你就可以控制隐藏的窗口何时被销毁。 我们在实时数据传输中使用了这种方法多年。

有后台线程删除内存是一个坏主意,并可能导致竞争条件,它不知道什么时候可以删除。 更好地张贴到自己的窗口,并删除它,当你完成它。

考虑UI线程的经典消息循环:

  MSG msg; while(GetMessage(&msg, NULL, 0, 0) > 0) { TranslateMessage(&msg); DispatchMessage(&msg); } 

从另一个线程发布的消息将被提取和分派,但是它的传递取决于目标窗口是否被成功创建(还没有被销毁)。 如果您有控制权,您可以考虑直接在消息循环中处理消息。 然而,当有另一个(嵌套的)消息循环时,事情会变得复杂,可以通过处理一些Windows消息来创建消息循环。 一个简单的例子是一个模式对话框,但是一些更复杂的事情,比如COM调用,也可能导致嵌套的消息循环。

因此,你不应该依靠保证的消息传递。 考虑使用像队列或列表这样的全局数据结构(通过关键部分同时访问来保护)来排列数据对象。 然后你仍然可以使用PostMessage传递一个消息,并在lParam传递一个指向你的数据对象的指针,但是在你的消息处理程序中,你需要在全局队列中找到对象并处理(或放弃)之前排队的对象,但由于某种原因还没有得到处理。 通常,当你的线程退出时( WM_QUIT消息到达上面的循环),你应该对队列中的任何东西进行一些处理。