WM_TIMER的陷阱

Purusa
木偶机器人 2012-06-07 字数 483

WM_TIMER的陷阱

最近一次痛苦的调试经历让我重现认识了WM_TIMER消息。为节省大家的时间,我就只

写结论:

1. WM_TIMER最好自己处理,不要注册回调函数。

2. 如果注册了回调函数,也要跟一个窗体关联。

3. 非要使用WM_TIMER的非窗体类回调函数,请记住,一定要在回调函数里处理**所有

的异常**, 因为任何未处理的异常都会被其调用者静默地吃掉! 到后来真是死都不知道

是怎么死掉的。

结论:避免在WM_TIMER的回调里做什么复杂的事情。

Reference:

1. http://msdn.microsoft.com/en-

us/library/windows/desktop/ms644907(v=vs.85).aspx

VisualC VC程序设计
26 个回复
hgoldfish
老鱼 2012-06-07

理由是什么?

【 在 Purusa (木偶机器人) 的大作中提到: 】

: WM_TIMER的陷阱

: 最近一次痛苦的调试经历让我重现认识了WM_TIMER消息。为节省大家的时间,我就只

: 写结论:

: ...................

goldold
梦子一,一子梦 2012-06-08

简单就是快乐

【 在 Purusa (木偶机器人) 的大作中提到: 】

: WM_TIMER的陷阱

: 最近一次痛苦的调试经历让我重现认识了WM_TIMER消息。为节省大家的时间,我就只

: 写结论:

: ...................

xiaoju
可爱的龙猫 2012-06-09

又不是由你家的cpp库回调的,凭什么不吃掉你的异常呢?

在所有地方都有类似的限制,这就是地球啊。

【 在 Purusa (木偶机器人) 的大作中提到: 】

: WM_TIMER的陷阱

: 最近一次痛苦的调试经历让我重现认识了WM_TIMER消息。为节省大家的时间,我就只

: 写结论:

: ...................

Purusa
木偶机器人 2012-08-09

问题是:

1. 文档里只字不提.

2. 同样是基于窗口的WM_TIMER回调,异常就是通透的。这一行为同样没有文档说明。

如果系统对此有默认行为, 文档里不提是可以理解的. 可是上面的情况说明系统的这种行为有多么坑害程序员了。操作系统当然可以有自己内部不公开的实现行为。可是当这种行为严重影响到API的使用者, 那就可以看作是一个bug了。

我吐槽是为了提醒大家这个bug的存在。您要自个觉得不是问题,请随便用。

【 在 xiaoju 的大作中提到: 】

: 又不是由你家的cpp库回调的,凭什么不吃掉你的异常呢?

: 在所有地方都有类似的限制,这就是地球啊。

xiaoju
可爱的龙猫 2012-08-09

建议你学习一下异常的原理。。

【 在 Purusa (木偶机器人) 的大作中提到: 】

: 标  题: Re: WM_TIMER的陷阱

: 发信站: 水木社区 (Thu Aug  9 03:14:41 2012), 站内

: 问题是:

: 1. 文档里只字不提.

: 2. 同样是基于窗口的WM_TIMER回调,异常就是通透的。这一行为同样没有文档说明。

: 如果系统对此有默认行为, 文档里不提是可以理解的. 可是上面的情况说明系统的这种行为有多么坑害程序员了。操作系统当然可以有自己内部不公开的实现行为。可是当这种行为严重影响到API的使用者, 那就可以看作是一个bug了。

: 我吐槽是为了提醒大家这个bug的存在。您要自个觉得不是问题,请随便用。

: 【 在 xiaoju 的大作中提到: 】

: : 又不是由你家的cpp库回调的,凭什么不吃掉你的异常呢?

: : 在所有地方都有类似的限制,这就是地球啊。

: :

: --

Purusa
木偶机器人 2012-08-09

hehe, 您要没看懂别人说什么,就别回贴,OK?

【 在 xiaoju 的大作中提到: 】

: 建议你学习一下异常的原理。。

goldold
梦子一,一子梦 2012-08-16

是的,能重入

【 在 Purusa (木偶机器人) 的大作中提到: 】

: WM_TIMER的陷阱

: 最近一次痛苦的调试经历让我重现认识了WM_TIMER消息。为节省大家的时间,我就只

: 写结论:

: ...................

goldold
梦子一,一子梦 2012-08-16

可以设置标志,执行函数时候该标志设置成0,执行完毕设置成1

在调用函数之前识别一下,如果,该函数没执行完就跳过去,这样就不会死机

【 在 goldold (梦子一,一子梦) 的大作中提到: 】

: 是的,能重入

zjudm
钱塘观潮 2012-08-16

嗯,当年俺也是这么处理的

【 在 goldold (梦子一,一子梦) 的大作中提到: 】

: 可以设置标志,执行函数时候该标志设置成0,执行完毕设置成1

: 在调用函数之前识别一下,如果,该函数没执行完就跳过去,这样就不会死机

xxp
华山令狐冲 2012-08-16

试了下,还真是。这个是挺可怕的。从你提供的那个link看,08年就有人抱怨了,他们也

一直没改。这个完全没道理,

一个是TimerProc,一个是WindowProc,前一个吃异常,后一个不吃。

【 在 Purusa (木偶机器人) 的大作中提到: 】

: 问题是:

: 1. 文档里只字不提.

: 2. 同样是基于窗口的WM_TIMER回调,异常就是通透的。这一行为同样没有文档说明。

: ...................

goldold
梦子一,一子梦 2012-08-16

是啊,请问几年的程序员?

【 在 zjudm (钱塘观潮) 的大作中提到: 】

: 嗯,当年俺也是这么处理的

zjudm
钱塘观潮 2012-08-16

俺是伪码农

【 在 goldold (梦子一,一子梦) 的大作中提到: 】

: 是啊,请问几年的程序员?

goldold
梦子一,一子梦 2012-08-16

国民党,伪军

【 在 zjudm (钱塘观潮) 的大作中提到: 】

: 俺是伪码农

wxstorm
企鹅 2012-08-19

伪军都是高帅富

【 在 goldold (梦子一,一子梦) 的大作中提到: 】

: 国民党,伪军

hhoking2012
中天 2012-11-08

是说回调函数会被重入,消息响应函数不会重入?

OLDGOLD
如风一般自由 2012-11-09

消息在消息队列里边排队,一旦有消息就立刻调用响应函数

实现消息循环,WM_TIMER的特点是重复性,一旦重入就很可能会引发接续重入

导致系统崩溃

【 在 hhoking2012 (中天) 的大作中提到: 】

: 是说回调函数会被重入,消息响应函数不会重入?

xiaoju
可爱的龙猫 2012-11-09

消息响应函数不可能重入,因为消息循环是单线程实现的。

【 在 hhoking2012 (中天) 的大作中提到: 】

: 是说回调函数会被重入,消息响应函数不会重入?

goldold
梦子一,一子梦 2012-11-09

问一下,消息循环是单线程的,那么,并发程序是怎么运行的呀

【 在 xiaoju (可爱的龙猫) 的大作中提到: 】

: 消息响应函数不可能重入,因为消息循环是单线程实现的。

hhoking2012
中天 2012-11-10

消息响应函数是可以重入的,就拿WM_TIMER来说,你在响应函数里做一个挂起看看?