Window SendMessage,PostMessage分析

背景

前段时间程序中突然出现一个Bug,程序会莫名其妙的卡一卡,每次卡个一秒左右,出现随机度高,定位了好久,好不容易才找到罪魁祸首。原来是SendMessage卡住了线程。那么就看看SendMessage的真面目吧。

SendMessage

函数原型

LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam)
参数
hWnd:指定要接收消息的窗口的句柄。如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。
Msg:指定被发送的消息。
wParam:指定附加的消息特定信息。
IParam:指定附加的消息特定信息。
返回值:返回值指定消息处理的结果,依赖于所发送的消息。

来自百度百科的介绍是这样的。
Windows API宏,在WinUser.h中根据是否已定义Unicode被定义为SendMessageW或SendMessageA,这两个函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。而和函数PostMessage不同,PostMessage是将一个消息寄送到一个线程的消息队列后就立即返回。
这个介绍中我们了解到原来SendMessage要等窗口程序处理完消息才返回,而他的另一个兄弟PostMessage则不需要等待,那PostMessage又是什么样的呢。

PostMessage

函数原型

BOOL WINAPI PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
hWnd:其窗口程序接收消息的窗口的句柄。可取有特定含义的两个值:
HWND_BROADCAST:消息被寄送到系统的所有顶层窗口,包括无效或不可见的非自身拥有的窗口、 被覆盖的窗口和弹出式窗口。消息不被寄送到子窗口
NULL:此函数的操作和调用参数dwThread设置为当前线程的标识符PostThreadMessage函数一样
Msg:指定被寄送的消息。
wParam:指定附加的消息特定的信息。
LParam:指定附加的消息特定的信息。
返回值:如果函数调用成功,返回非零,否则函数调用返回值为零
PostMessage的百度百科介绍是这样的。
PostMessage是Windows API(应用程序接口) 中的一个常用函数,用于将一条消息放入到消息队列中。消息队列里的消息通过调用GetMessage和PeekMessage取得。

区别

阻塞性:
SendMessage是阻塞的,消息发送被处理之后返回,也就是如果发送给其他线程或进程的时候,发送的进程会卡住
PostMessage是非阻塞的,消息发送了之后立马返回,不管消息被处理需要多久
消息处理方式:
SendMessage是进程的msgproc直接接受到消息进行处理。
PostMessage的消息是被放在消息队列中,需要主动去取,通过调用GetMessage和PeekMessage取得

问题解决

而我遇到的问题,就是接收消息的线程处理的太慢,导致我发送的线程卡住了,这个时候我有两个选择
1.使用PostMessage,这样的话需要接收方配合做一些修改,也就是说本来可以用的东西,可能会出问题,不是最好的方案
2.我把我的发送消息发送到一个可以被阻塞的地方,也就是新建一个新的线程,只负责发送消息,这样改动最小的情况下,达成了我的目标。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值