为啥我的 DCOM 客户端会锁定对 SendMessage 的调用?
Posted
技术标签:
【中文标题】为啥我的 DCOM 客户端会锁定对 SendMessage 的调用?【英文标题】:Why is my DCOM client locking on a call to SendMessage?为什么我的 DCOM 客户端会锁定对 SendMessage 的调用? 【发布时间】:2010-02-23 17:48:56 【问题描述】:在 XP 上运行。我有一个调用CoInitializeEx(NULL, COINIT_MULTITHREADED)
的客户端,加载一个(本地)DCOM 对象,并附加一个事件接口,以便DCOM 对象可以发回事件。客户端看起来很像记事本,带有覆盖客户区域的多行文本框以显示事件消息。以下是造成锁定的调用:
p->DoStuff()
。
DCOM 对象在处理DoStuff()
时在客户端调用c->DoStuffEvent()
。
客户端向子文本框发送EM_REPLACESEL
消息,使其显示“正在发生的事情”
客户端冻结在SendMessage(EM_REPLACESEL)
。客户端对p->DoStuff()
的调用在主线程上完成,而SendMessage(EM_REPLACESEL)
在不同线程上完成。我确定这与问题有关。
谁能解释导致锁定的原因以及我可以如何解决它?客户端和 DCOM 对象由我在 MSVC/ATL 中编码,因此我可以根据需要修改它们。
【问题讨论】:
【参考方案1】:看起来窗口是由主线程创建的。所以这是唯一可以调用窗口过程的线程。当你从另一个线程SendMessage
时,它实际上将消息放入主线程的队列,然后等待主线程调用GetMessage
或PeekMessage
。在对GetMessage
或PeekMessage
的调用中,Windows 注意到一个等待的交叉线程SendMessage
并将该消息传递给窗口进程,然后唤醒第二个线程并让它继续。
如果你不关心SendMessage(EM_REPLACESEL)
的返回值,你可以用SendNotifyMessage代替。但是如果你这样做,你需要确保你通过EM_REPLACESEL
消息传递的字符串在消息最终被传递时仍然有效。
【讨论】:
是的,现在这很有意义。谢谢。【参考方案2】:根据SendMessage 文档,SendMessage 在函数完成之前不会返回。它是同步的。我相信它也总是在 UI 线程上得到回答。如果你想做一个异步消息传递,那么你应该使用PostMessage。
【讨论】:
以上是关于为啥我的 DCOM 客户端会锁定对 SendMessage 的调用?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的 Service Fabric 代码会锁定自己的 PDB?
为啥我的 PDF 生成进程会锁定我站点中的其他 ajax 进程?