2010-02-23 3 views
2

XP에서 실행 중입니다. CoInitializeEx(NULL, COINIT_MULTITHREADED)을 호출하고 (로컬) DCOM 개체를로드하고 DCOM 개체가 이벤트를 다시 보낼 수 있도록 이벤트 인터페이스를 연결하는 클라이언트가 있습니다. 클라이언트는 클라이언트 영역을 포함하는 여러 줄의 텍스트 상자를 사용하여 메모장처럼 보이게하여 이벤트 메시지를 표시합니다. 잠김을 만드는 호출은 다음과 같습니다.SendMessage 호출시 DCOM 클라이언트가 잠기는 이유는 무엇입니까?

  • 클라이언트는 DCOM 개체에 p->DoStuff()을 호출합니다.
  • DoStuff()을 처리하는 동안 DCOM 개체가 클라이언트의 c->DoStuffEvent()을 호출합니다.
  • 클라이언트는 클라이언트가 SendMessage(EM_REPLACESEL)에 얼어

"물건이 일어나고있다"를 표시하도록 자식 텍스트 상자에 EM_REPLACESEL 메시지를 보냅니다. p->DoStuff()에 대한 클라이언트 호출은 메인 스레드에서 수행되고 SendMessage(EM_REPLACESEL)은 다른 스레드에서 수행됩니다. 이것이 문제와 관련이 있다고 확신합니다.

누군가가 자물쇠의 원인을 설명하고 내가 어떻게 해결할 수 있습니까? 클라이언트와 DCOM 객체는 MSVC/ATL에서 나로 코딩되었으므로 필요에 따라 둘 다 수정할 수 있습니다.

답변

3

창이 메인 스레드에 의해 생성 된 것으로 보입니다. 그래서 이것이 window proc를 호출 할 수있는 유일한 스레드입니다. 다른 스레드의 SendMessage이 메시지를 주 스레드의 큐에 넣은 다음 주 스레드가 GetMessage 또는 PeekMessage을 호출하기를 기다리는 것은 실제로 무엇을합니까? GetMessage 또는 PeekMessage에 대한 호출에서 Windows는 대기중인 크로스 스레드 SendMessage을 확인하고 해당 메시지를 창 proc에 전달한 다음 두 번째 스레드를 깨우고 계속 진행할 수 있습니다.

SendMessage(EM_REPLACESEL)의 반환 값에 대해 신경 쓰지 않는다면 SendNotifyMessage을 대신 사용할 수 있습니다. 그러나 이렇게하면 EM_REPLACESEL 메시지와 함께 전달 된 문자열이 메시지가 최종적으로 전달 될 때 여전히 유효한지 확인해야합니다.

+0

예, 이제 완벽하게 이해할 수 있습니다. 고맙습니다. – Charles

1

SendMessage 설명서에 따라 SendMessage는 함수가 완료 될 때까지 반환되지 않습니다. 동기식입니다. 난 항상뿐만 아니라 UI 스레드에서 대답 믿습니다. 비동기 메시지 전달을 원하면 PostMessage을 사용해야합니다.

관련 문제