MFC:从另一个线程调用CWnd方法是否安全?

时间:2018-01-22 10:07:34

标签: c++ multithreading mfc sendmessage cwnd

其实我有两个问题:

  1. 从工作线程调用SendMessage是否安全?
  2. CWnd方法,如MessageBox,在场景后面调用API函数SendMessage吗?
  3. 根据我的理解,当工作线程调用SendMessage时,它会将消息推送到UI线程的消息队列中,并等待直到处理此消息。在这种情况下,这样做是安全的。

    我对此并不十分肯定。如果我错了,请纠正我。

    非常感谢。

    ------------------------ update ---------------------- ------------

    作为结论:

    • 跨线程调用Windows API ::SendMessage::PostMessage是安全的。
    • 跨线程调用CWnd方法是不安全的。有些方法可能是安全的,但不能保证。

    非常感谢大家。

2 个答案:

答案 0 :(得分:5)

  

从工作线程调用SendMessage是否安全?

是。系统确保在接收线程上序列化消息处理。通过线程发送邮件时,发件人将被阻止,直到邮件被处理完毕。接收方在执行消息检索代码(GetMessagePeekMessage等)时仅处理跨线程发送的消息。发送的消息永远不会在消息队列中排队。 SendMessage的文档包含其他详细信息。

  

CWnd方法,如MessageBox,在场景后面调用API函数SendMessage吗?

是。例如,消息框将接收标准窗口消息,如WM_CREATEWM_NCCREATE,作为对话框构造的一部分。此外,对于拥有的窗口(如模态对话框),系统将向正在停用的窗口和正在激活的窗口发送WM_ACTIVATE消息。我不确定为什么这很重要,或者为什么你特别提出这个问题。

现在标题中的问题:

  

从另一个线程调用CWnd方法是否安全?

一般来说,没有。但这取决于会员。有些人可以安全地打电话,有些人则没有。特别是,只应从创建窗口的线程调用修改窗口状态(内容,可见性,激活等)的所有方法。如果呼叫不安全,系统仍将处于一致状态。但是,您的申请可能不是。

答案 1 :(得分:1)

线程访问用户界面的方式是使用SendMessagePostMessage

考虑一台具有一个核心的机器,在这里发生上下文切换,并且您可以从工作线程直接访问UI,您可能会破坏UI线程寄存器!

基本上每个UI框架都提供了一种机制(多次),用于从线程进行UI更改。例如,Android提供了ASyncTaskHandler