问题
Actually I have two questions:
- Is it safe to call
SendMessage
from a worker thread? - Do
CWnd
methods, likeMessageBox
, call API functionSendMessage
behind the scene?
Per my understanding, when the worker thread calls SendMessage
, it pushes the message into the message queue of the UI thread, and waits until this message is processed. In that case, it would be safe to do so.
I'm not quite sure about this. please correct me if I was wrong.
Thanks a lot.
------------------------ update ----------------------------------
As a conclusion:
- It's safe to call the windows API
::SendMessage
and::PostMessage
across threads. - It's not safe to call
CWnd
methods across threads. Some of the methods may be safe, but it's not guaranteed.
Great thanks to everyone.
回答1:
Is it safe to call
SendMessage
from a worker thread?
Yes. The system makes sure, that message handling is serialized on the receiving thread. When sending messages across threads, the sender is blocked until the message has been handled. The receiver only handles a cross-thread sent message when it executes message retrieval code (GetMessage
, PeekMessage
, etc.). Sent messages are never queued in the message queue. The documentation for SendMessage has additional details.
Do
CWnd
methods, likeMessageBox
, call API functionSendMessage
behind the scene?
Yes. For one, the message box will receive standard window messages like WM_CREATE
or WM_NCCREATE
as part of the dialog construction. Also, for owned windows (like modal dialogs), the system will send WM_ACTIVATE
messages to both the window being deactivated, and the window being activated. I'm not sure why this matters, though, or why you asked this question in particular.
Now the question in your title:
Is it safe to call
CWnd
methods from another thread?
In general, no. It does depend on the member, though. Some are safe to call, others aren't. In particular, all methods that modify window state (contents, visibility, activation, etc.) should only be called from the thread that created the window. In case the call is not safe, the system will still be in a consistent state. However, your application may not be.
回答2:
The ONLY way for a thread to access the UI is by using SendMessage
or PostMessage
.
Consider a machine with one core, where context switching occurs and you make direct access to the UI from a worker thread, you are potentially corrupting the UI thread registers !
Basically every UI framework offers a mechanism (many times several), for making UI changes from a thread. For instance Android offers an ASyncTask
and a Handler
.
来源:https://stackoverflow.com/questions/48379003/mfc-is-it-safe-to-call-cwnd-methods-from-another-thread