Почему мой клиент DCOM блокирует вызов SendMessage? - PullRequest
2 голосов
/ 23 февраля 2010

работает на XP. У меня есть клиент, который вызывает звонки 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, поэтому я могу изменить их оба при необходимости.

Ответы [ 2 ]

3 голосов
/ 23 февраля 2010

Похоже, что окно было создано основным потоком. Так что это единственный поток, который может вызывать процедуру окна. Когда вы SendMessage из другого потока, что он на самом деле делает, чтобы поместить сообщение в очередь основного потока, а затем ждать, пока основной поток вызовет GetMessage или PeekMessage. Внутри вызова к GetMessage или PeekMessage Windows замечает ожидающий кросс-поток SendMessage и передает это сообщение в оконный процесс, затем пробуждает второй поток и позволяет продолжить.

Если вас не волнует возвращаемое значение SendMessage(EM_REPLACESEL), вы можете использовать SendNotifyMessage . Но если вы сделаете это, вам нужно убедиться, что строка, которую вы передаете с сообщением EM_REPLACESEL, остается действительной, когда сообщение наконец доставлено.

1 голос
/ 23 февраля 2010

Согласно документации SendMessage , SendMessage не возвращается, пока функция не будет завершена. Это синхронно. Я верю, что на UI также всегда есть ответ. Если вы хотите выполнить асинхронную передачу сообщений, вам следует использовать PostMessage .

...