【发布时间】:2018-08-30 08:23:07
【问题描述】:
我正在开发一个需要在 COM STA 线程上从另一个线程执行代码的 C++ MFC/COM 应用程序(包括 VBA 和 .NET 代码)。
一种可行的方法是使用PostMessage 函数将消息发布到隐藏的HWND_MESSAGE 窗口,但速度很慢(在我的应用程序中,以这种方式进入 STA 可能需要大约 4 毫秒。
改为使用SendNotifyMessage 会明显更快。在这种情况下,到达 STA 需要
由于应用程序的性质和发生的调用次数(我无法控制),这种差异很重要。不幸的是,我遇到了难以查明的奇怪错误。有些可能与 STA 重入有关,例如,如果某些 .NET 代码在内部泵送消息同时阻塞 WaitHandle.WaitOne 我注意到重入。 VBA 也参与其中。
我的问题是:
- 可以使用
SendNotifyMessage代替PostMessage进入STA 线程吗? - 如果是这样,有没有办法让它与 .NET 一起“玩得很好”? (使其成为非阻塞或使用阻塞非泵送等待不是一种选择)
- (奖励)
SendNotifyMessage是如何如此快速地进入 STA 线程的?
【问题讨论】:
-
恕我直言,为了“玩得开心”,使用官方方式在 COM 对象之间进行通信,不使用异国管道。你有需要这一切的理由吗?
-
PostMessage 的问题最终在于线程唤醒、泵送消息并传递它需要时间。 SendNotifyMessage 接缝是一个快捷方式。但是它将其消息放在必须传递的消息列表的顶部,因此它绕过了使用 PostMessage 启动的其他消息,我将使用一个简单的普通 STA COM 方式来完成这一切......编组一个 COM 指针并使用它...
-
窗口消息总是在拥有窗口的线程上发送。此问题中的任何一个 API 调用随后都会在拥有(仅消息)窗口的线程上运行代码。我不确定您遇到了什么问题,但重入很可能是原因之一。 When can a thread receive window messages? 可能是相关阅读。
-
@xMRi:
PostMessage不需要等待接收者唤醒和发送消息。它只是将消息排入消息队列,然后返回。另一方面,SendMessage要求接收线程正在运行,并调用任一消息检索函数。 -
@IInspectable:我没有写过关于 SendMessage 的文章,我也知道 PostMessage 的行为。我的评论有什么问题?我只想说,在 PostMessage 执行后,另一个线程会唤醒并获取消息需要时间...... SendNotifyMessage 一次完成这一切......