是否需要手动释放一次性定时器?
我们可以通过调用CreateTimerQueueTimer这个API来创建一个一次性定时器,只需传递一个WT_EXECUTEONLYONCE标志就行。如果你仔细阅读开发文档,则会发现文档有这么一句话:当你不再需要使用定时器时,你需要调用DeleteTimerQueueTimer来释放定时器。
问题来了:既然是一个一次性的定时器,为啥还需要手动释放它呢?
为了回答这个问题,我想向你介绍一套关于解答此类问题的一种标准技法:让我们假设,这个定时器使用之后,我们不释放它,看看会发生什么?
一方面,这会导致API的行为看起来很怪异。调用者调用CreateTimerQueueTimer函数后,需要跟踪定时器的属性(例如它是一次性的还是其他类型的),还需要知道定时器的句柄是否需要被删除。
更糟糕的是,如果一次性定时器是可以实现自动释放的,则调用者几乎不太可能正确地使用它。
假设,你有一个对象,它创建了一个一次性定时器,你希望在对象的析构函数中释放它。如果这个定时器是自动释放的,则就不可能像下图这样编写代码:
你可能会说,”我可以设计一个回调函数来将这个m_hTimer变量设置为空。这样,析构函数就知道定时器被激活过了。”
但是,这会导致一个潜在的竞争条件(Race Condition),如下图所示:
如果在竞争条件期间回调被抢占并且对象被析构,并且一次性定时器正在自动释放,那么对象将会使用无效的句柄。
这个竞争条件窗口是无法关闭的,因为竞争条件甚至在你有机会执行一行代码之前就已经发生了。
所以,请开心笑纳:你必须手动释放一次性计时器的句柄。
总结
对于实现了自动释放的对象来说,要么它完美地实现了自动化释放,这样调用者就不用太关心调用细节(干就完了)。
要么,还是老老实实将控制权交给调用者吧。
最后
Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《Do you need clean up one-shot timers?》
最近我写了个东西
正如你们所知道的,拓扑梅尔智慧办公平台(Topomel Box)是一款绿色软件,主要面向经常使用电脑的朋友。它提供了各种提升办公效率的小功能,同时操作上尽可能地简单方便。
我想:你值得拥有。
- 下一篇: 编写现代C++代码:GSL 4.0.0 正式可用
- 上一篇: 关于布尔类型的几个变种的解释
相关推荐
- 即使运行高优先级线程,低优先线程也能运行
- Posted on 04月22日
- 参考:TCP/UDP 端口号范围
- Posted on 09月15日
- 关于命令行长度限制
- Posted on 08月20日
- 为什么不能在一个禁用的窗口上显示工具提示?
- Posted on 02月19日
评论已关闭。