2010-02-23 46 views
2

在XP上运行。我有一个客户端调用调用CoInitializeEx(NULL, COINIT_MULTITHREADED),加载(本地)DCOM对象,并附加一个事件接口,以便DCOM对象可以发回事件。客户端看起来很像记事本,其中多行文本框覆盖客户区以显示事件消息。以下是创建锁定的呼叫:为什么我的DCOM客户端锁定对SendMessage的调用?

  • 客户端在DCOM对象上调用p->DoStuff()
  • 在处理DoStuff()时,DCOM对象在客户端上调用c->DoStuffEvent()
  • 客户端发送一个EM_REPLACESEL消息,孩子的文本框,以使其显示“的东西正在发生的事情”

客户端的瞬间将SendMessage(EM_REPLACESEL)。客户对p->DoStuff()的调用在主线程上完成,而SendMessage(EM_REPLACESEL)在不同线程上完成。我相信这与问题有关。

有人可以解释是什么导致了锁,以及我可以如何解决它?客户端和DCOM对象由我在MSVC/ATL中编码,所以我可以根据需要对它们进行修改。

回答

3

看来窗口是由主线程创建的。所以这是唯一可以调用窗口过程的线程。当你从另一个线程SendMessage,它实际上把它放到主线程的队列中,然后等待主线程调用GetMessagePeekMessage。在GetMessagePeekMessage的调用中,Windows通知等待的跨线程SendMessage并将该消息传递给窗口proc,然后唤醒第二个线程并让其继续。

如果您不在意SendMessage(EM_REPLACESEL)的返回值,则可以使用SendNotifyMessage代替。但是,如果您这样做,则需要确保在消息最终传递时,通过EM_REPLACESEL消息的字符串仍然有效。

+0

是的,这现在非常有意义。谢谢。 – Charles 2010-02-23 18:23:50

1

根据SendMessage文档,SendMessage不会返回,直到函数完成。它是同步的。我相信它总是在UI线程上得到解答。如果您想执行异步消息传递,那么您应该使用PostMessage

相关问题