解析SendMessage和PostMessage的区别

来源:互联网 发布:源码 反码 补码 编辑:程序博客网 时间:2024/06/04 18:15

从MSDN上的说明来看,PostMessage将消息寄送到目标消息队列后立即返回。所以返回值是布尔型,只有成功和不成功。而SendMessage把消息寄送过去以后,要等目标窗口的窗口过程函数处理完,return一个值以后才返回。怎么理解呢。这样来说把,有AB两个线程,B线程是UI线程,有一个窗口。A线程用SendMessage给B线程的窗口发送了一个消息,B线程接收到消息后调用对应的窗口过程函数来处理这个消息。这个函数结束后把返回值告诉A线程,A线程的SendMessage的返回值就是这个值。但如果B线程接到A线程发来的消息后,处理这个消息需要很长的时间。那么A线程也只能一直等,一直等到B线程处理完返回值后,A线程才能继续运行。而PostMessage则不同,用PostMessage的话,A线程给B线程发送消息后就不管了,接着往下运行,B线程怎么处理是它的事。不管B线程要处理多久,A线程也不会作等待。

我们在MFC里写这样一段代码来测试:

#define WM_OK (WM_USER+1)UINT Run(LPVOID p){HWND hwnd = (HWND)p;UINT i = ::SendMessage(hwnd,WM_OK,NULL,NULL);CString str;str.Format(L"完成,返回值为%d",i);::MessageBox(NULL,str,NULL,NULL);return 0;}void CmessageDlg::OnBnClickedOk(){AfxBeginThread(Run,GetSafeHwnd());}afx_msg LRESULT CmessageDlg::OnOk(WPARAM wParam, LPARAM lParam){Sleep(3000);return 100;}


 

我们开一个线程,用SendMessage方式对主线程的窗口发送一个自定义消息WM_OK,主线程接收到这个消息后Sleep睡上3秒钟才返回100这个值。运行后发现,我们开的这个线程,过了3秒才弹出MessageBox,那3秒它干什么去了?原来是SendMessage这里,它等待了3秒。因为主线程3秒后才返回值给它,他就必须等上3秒

我们把SendMessage换成PostMessage后,运行,无须等待,我们开的线程就弹出了MessageBox。说明线程采用PostMessage方式发送消息,它不等结果,直接就往下运行了。

知道了这些后,我们在实际编程过程中就应该注意了。我们可以在A线程中的栈上创建一个变量,然后把这个变量的地址(指针)通过消息发送到B线程,B线程可以用这个地址(指针)来读写这个变量的值。这种情况下我们应该使用SendMessage方式来发送消息,因为A线程会等待B线程处理结束。如果我们用PostMessage方式来发送的话。当B线程接收到那个指针后,可能A线程已经结束退出了,栈已经被清理了,而B线程再来访问那个指针处的值,程序就崩溃了。这种情况下,我们应该用SendMessage而不用PostMessage。

但有的时候我们应该用PostMessage而不用SendMessage,因为用SendMessage的话,A线程会一直等待B线程处理完这个消息。如果这个消息B线程需要处理很长时间的话,A线程得一直等待。如果A线程仅仅是想把消息发给B线程,不需要知道B线程处理的结果如何。尤其是B线程需要很长时间来处理这个消息的情况下。应该用PostMessage,这样,A线程就不会一直在等待了。

原创粉丝点击