2

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

  • 客户端调用p->DoStuff()DCOM 对象。
  • DCOM 对象c->DoStuffEvent()在处理时调用客户端DoStuff()
  • 客户端向子文本框发送一条EM_REPLACESEL消息,让它显示“事情正在发生”

客户端冻结在SendMessage(EM_REPLACESEL). 客户端的调用p->DoStuff()在主线程上SendMessage(EM_REPLACESEL)完成,而在不同的线程上完成。我确定这与问题有关。

有人可以解释导致锁定的原因以及我如何解决它吗?客户端和 DCOM 对象由我在 MSVC/ATL 中编码,因此我可以根据需要修改它们。

4

2 回答 2

3

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

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

于 2010-02-23T18:13:14.433 回答
1

根据SendMessage文档,SendMessage 在函数完成之前不会返回。它是同步的。我相信它也总是在 UI 线程上得到回答。如果要进行异步消息传递,则应使用PostMessage

于 2010-02-23T18:07:58.737 回答