Why is my DCOM client locking on a call to SendMessage?
Running on XP. I have a client that calls calls CoInitializeEx(NULL, COINIT_MU开发者_如何学运维LTITHREADED)
, loads a (local) DCOM object, and attaches an event interface so the DCOM object can send back events. The client looks a lot like notepad with a multi-line textbox covering the client area to display event messages. Here are the calls that create a lock-up:
- Client calls
p->DoStuff()
on the DCOM object. - The DCOM object calls
c->DoStuffEvent()
on the client while processingDoStuff()
. - The client sends a
EM_REPLACESEL
message to the child textbox to have it display "stuff is happening"
The client freezes on the SendMessage(EM_REPLACESEL)
. The client's call to p->DoStuff()
is done on a the main thread while the SendMessage(EM_REPLACESEL)
is done on a different thread. I'm sure this has something to do with the problem.
Can someone explain what's causing the lock and how I might work around it? The client and DCOM objects are coded by me in MSVC/ATL, so I can modify them both as needed.
It would appear that the window was created by the main thread. So that is the only thread that can call the window proc. When you SendMessage
from the other thread, what it actually does it to put the message into the main thread's queue and then wait for the main thread to call GetMessage
or PeekMessage
. Inside the call to GetMessage
or PeekMessage
, Windows notices a waiting cross-thread SendMessage
and passes that message to the window proc, then it wakes the second thread and lets it continue.
If you don't care about the return value of SendMessage(EM_REPLACESEL)
, you can use SendNotifyMessage instead. But if you do this, you need to make sure that the string you pass with the EM_REPLACESEL
message is still valid when the message is finally delivered.
As per the SendMessage documentation, SendMessage does not return until the function is completed. It is synchronous. I believe it is always answered on the UI thread as well. If you want to do an asynchronous message pass, then you should use PostMessage.
精彩评论