Windows中子线程不能触发定时器的问题分析
2013-09-03 14:04
267 查看
对窗口来说,都会有一个消息循环线程(此消息线程即UI线程)执行各类任务,一般情况此线程大部分时间都处于空闲状态,由消息泵等待消息触发各类操作(如界面刷新、定时器响应等),除非窗口退出,不然不会退出此线程。 在窗口线程或主线程中使用定时器由于有消息泵等待定时器消息,所以不会存在不响应定时器的情况。但子线程在创建时一般不需要消息泵,所以按顺序执行完后直接退出,就算是有定时器需要触发,子线程也不知道,所以等定时器Timeout时,并不会达到触发的目的。
解决办法1、所有触发定时器的操作转到主线程执行 此方法是碰到此问题时首先想到的解决方法,也是简单可行的,但某些情况可能就要改变定时器的触发方式,在修改时会比较花时间。最关键的是:此方法是在逃避问题而不是迎接问题。2、在子线程加入消息泵 问题的本质也清楚了,那在子线程中加入消息泵即可完美解决此类问题。需要在有触发定时器的线程中加入PeekMsg()函数(代码如下),如果响应完后退出线程,直接在响应过程后退出while循环可以达到目的。
解决办法1、所有触发定时器的操作转到主线程执行 此方法是碰到此问题时首先想到的解决方法,也是简单可行的,但某些情况可能就要改变定时器的触发方式,在修改时会比较花时间。最关键的是:此方法是在逃避问题而不是迎接问题。2、在子线程加入消息泵 问题的本质也清楚了,那在子线程中加入消息泵即可完美解决此类问题。需要在有触发定时器的线程中加入PeekMsg()函数(代码如下),如果响应完后退出线程,直接在响应过程后退出while循环可以达到目的。
void PeekMsg() { MSG msg; PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); while(1) { if(GetMessage(&msg, NULL, 0, 0)) { switch(msg.message) case WM_TIMER: { ::DispatchMessage(&msg); break; } } } }经验证,以上方法是正确的,但需要根据实际问题进行一些调整完善。
相关文章推荐
- Windows中子线程不能触发定时器的问题分析
- Linux和Windows区别分析之线程问题
- 关于spring定时器一次调用却触发了两次trigger的问题分析
- 多线程委托之跨线程问题分析--在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke(解决方法已更新)
- 关于spring定时器一次调用却触发了两次trigger的问题分析
- c#中跨线程调用windows窗体控件 .我们在做winform应用的时候,大部分情况下都会碰到使用多线程控制界面上控件信息的问题。然而我们并不能用传统方法来做这个问题,下面我将详细的介绍。
- linux 和 windows C++ 子线程编程中子线程的退出——总结
- 子目录下的JSP不能访问类的问题分析
- 深度分析 Java 的枚举类型:枚举的线程安全性及序列化问题
- 如何解决 WebSphere MQ V6.0 通道不能被触发的问题?
- 解决beyond compare不能比较windows 和 mac os x 10.9 Mavericks 两者文件夹的问题。
- CAsyncSocket对象不能跨线程之分析 (转载)
- 谈谈VxWorks下FTP Server不能被普通Windows FTP Client访问的问题
- 郁闷的SQL问题-不能通过Windows身份验证远程登录
- 安装Windows 8.1过程中出现的各种问题(无损从MBR转GPT磁盘、不能定位已有分区)
- 解决 Updatedata不能更新、报错问题。(主要是不同的类、线程中出现的)
- Android中子线程真的不能更新UI吗?
- Windows Movie Maker XP不能保存视频问题完全解决!
- 混淆后APK百度地图不能正常使用问题分析
- 解决Redis局域网内不能访问的问题(Windows/Linux)