На самом деле у меня есть два вопроса:
SendMessage
из рабочего потока?CWnd
методы, как MessageBox
вызовите функцию API SendMessage
за кулисами?Насколько я понимаю, когда рабочий поток вызывает SendMessage
он помещает сообщение в очередь сообщений потока пользовательского интерфейса и ожидает обработки этого сообщения. В этом случае было бы безопасно сделать это.
Я не совсем уверен в этом. Пожалуйста, поправьте меня, если я был неправ.
Большое спасибо.
———————— Обновить ———————————-
В заключение:
::SendMessage
а также ::PostMessage
через темы.CWnd
методы через потоки. Некоторые из методов могут быть безопасными, но это не гарантировано.Большое спасибо всем.
Это безопасно звонить
SendMessage
из рабочего потока?
Да. Система обеспечивает сериализацию обработки сообщений в принимающем потоке. При отправке сообщений через потоки отправитель блокируется до тех пор, пока сообщение не будет обработано. Получатель обрабатывает отправленное сообщение между потоками только при выполнении кода извлечения сообщения (GetMessage
, PeekMessage
, так далее.). Отправленные сообщения никогда не ставятся в очередь в очереди сообщений. Документация для Отправить сообщение имеет дополнительные детали.
Делать
CWnd
методы, какMessageBox
вызовите функцию APISendMessage
за кулисами?
Да. Например, окно сообщений будет получать стандартные оконные сообщения, такие как WM_CREATE
или же WM_NCCREATE
как часть построения диалога. Кроме того, для собственных окон (например, модальных диалогов) система отправит WM_ACTIVATE
сообщения как для деактивируемого окна, так и для активируемого окна. Я не уверен, почему это важно, или почему вы задали этот вопрос в частности.
Теперь вопрос в вашем названии:
Это безопасно звонить
CWnd
методы из другого потока?
В общем нет. Это зависит от члена, хотя. Некоторым безопасно звонить, другим нет. В частности, все методы, которые изменяют состояние окна (содержимое, видимость, активация и т. Д.), Должны вызываться только из потока, создавшего окно. В случае, если вызов небезопасен, система все еще будет в согласованном состоянии. Тем не менее, ваша заявка не может быть.
ТОЛЬКО способ получить доступ к интерфейсу потока с помощью SendMessage
или же PostMessage
,
Рассмотрим машину с одним ядром, где происходит переключение контекста, и вы делаете прямой доступ к пользовательскому интерфейсу из рабочего потока, вы потенциально портите регистры потока пользовательского интерфейса!
По сути, каждая структура пользовательского интерфейса предлагает механизм (многократно несколько) для внесения изменений в пользовательский интерфейс из потока. Например, Android предлагает ASyncTask
и Handler
,