2010-02-23 75 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

相關問題