MFC: Безопасно ли вызывать методы CWnd из другого потока?

На самом деле у меня есть два вопроса:

  1. Это безопасно звонить SendMessage из рабочего потока?
  2. Делать CWnd методы, как MessageBoxвызовите функцию API SendMessage за кулисами?

Насколько я понимаю, когда рабочий поток вызывает SendMessageон помещает сообщение в очередь сообщений потока пользовательского интерфейса и ожидает обработки этого сообщения. В этом случае было бы безопасно сделать это.

Я не совсем уверен в этом. Пожалуйста, поправьте меня, если я был неправ.

Большое спасибо.

———————— Обновить ———————————-

В заключение:

  • Безопасно вызывать Windows API ::SendMessage а также ::PostMessage через темы.
  • Не безопасно звонить CWnd методы через потоки. Некоторые из методов могут быть безопасными, но это не гарантировано.

Большое спасибо всем.

2

Решение

Это безопасно звонить SendMessage из рабочего потока?

Да. Система обеспечивает сериализацию обработки сообщений в принимающем потоке. При отправке сообщений через потоки отправитель блокируется до тех пор, пока сообщение не будет обработано. Получатель обрабатывает отправленное сообщение между потоками только при выполнении кода извлечения сообщения (GetMessage, PeekMessage, так далее.). Отправленные сообщения никогда не ставятся в очередь в очереди сообщений. Документация для Отправить сообщение имеет дополнительные детали.

Делать CWnd методы, как MessageBoxвызовите функцию API SendMessage за кулисами?

Да. Например, окно сообщений будет получать стандартные оконные сообщения, такие как WM_CREATE или же WM_NCCREATE как часть построения диалога. Кроме того, для собственных окон (например, модальных диалогов) система отправит WM_ACTIVATE сообщения как для деактивируемого окна, так и для активируемого окна. Я не уверен, почему это важно, или почему вы задали этот вопрос в частности.

Теперь вопрос в вашем названии:

Это безопасно звонить CWnd методы из другого потока?

В общем нет. Это зависит от члена, хотя. Некоторым безопасно звонить, другим нет. В частности, все методы, которые изменяют состояние окна (содержимое, видимость, активация и т. Д.), Должны вызываться только из потока, создавшего окно. В случае, если вызов небезопасен, система все еще будет в согласованном состоянии. Тем не менее, ваша заявка не может быть.

5

Другие решения

ТОЛЬКО способ получить доступ к интерфейсу потока с помощью SendMessage или же PostMessage,

Рассмотрим машину с одним ядром, где происходит переключение контекста, и вы делаете прямой доступ к пользовательскому интерфейсу из рабочего потока, вы потенциально портите регистры потока пользовательского интерфейса!

По сути, каждая структура пользовательского интерфейса предлагает механизм (многократно несколько) для внесения изменений в пользовательский интерфейс из потока. Например, Android предлагает ASyncTask и Handler,

1