- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在我的应用程序中使用计时器队列,并将指向我自己的 C++ 计时器对象之一的指针作为“参数”传递给回调(在 CreateTimerQueueTimer 中)。然后,我在回调中对对象调用虚拟方法。
Timer 对象的析构函数将确保使用 DeleteTimerQueueTimer() 取消计时器。
static void callback( PVOID param, BOOLEAN timerOrWaitFired )
{
Timer* timer = reinterpret_cast< Timer* >( param );
timer->TimedOut();
}
class Timer
{
public:
Timer();
virtual ~Timer()
{
::DeleteTimerQueueTimer( handle );
}
void Start( double period )
{
::CreateTimerQueueTimer( &handle, ..., &callback, this, ... );
}
virtual void TimedOut() = 0;
...
};
但是,存在一个微妙的竞争条件,如果回调已被调用,但定时器对象在调用 TimedOut() 之前被销毁,应用程序崩溃,因为回调调用虚拟不存在的对象上的方法。甚至更糟的是,它正在被删除。
我确实有适当的互斥锁来控制多线程调用,但我仍然遇到问题。
使用对象指针作为回调参数真的是个好主意吗?由于无法保证线程之间的同步,这对我来说很难闻。
有更好的解决方案吗?其他人做什么?
发生的一件事是保留一组指向每个 Timer 实例的指针(在构造函数中添加,在析构函数中删除)。但我认为这行不通,因为如果 Timer 派生自,我们只会从基类析构函数中的集合中删除指针;如果我们已经开始销毁派生对象,那么损害就已经造成了。
干杯。
最佳答案
使用对象指针作为回调函数参数的概念本身并不坏。但是,您显然需要在最后一个回调退出后开始销毁。
因此,我根本不会将 Timer 抽象化并派生自它。我会使用另一个抽象类 TimerImpl
并使 Timer
类使用 TimerImpl
实例:
class Timer
{
TimerInstance* impl;
void TimeOut() { impl->TimeOut(); }
public:
~Timer() {
... make sure the timer has ended and wont fire again after this line...
delete impl;
}
}
struct TimerImpl
{
virtual void TimeOut()=0;
virtual ~TimerImpl();
}
这样,您可以确保破坏不会在您说完之前开始。
第二件事是,你必须等待最后一个计时器事件耗尽。根据MSDN doc , 你可以调用
DeleteTimerQueueTimer(TimerQueue, Timer, INVALID_HANDLE_VALUE)
关于c++ - CreateTimerQueueTimer 回调和竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/476865/
我在我的应用程序中使用计时器队列,并将指向我自己的 C++ 计时器对象之一的指针作为“参数”传递给回调(在 CreateTimerQueueTimer 中)。然后,我在回调中对对象调用虚拟方法。 Ti
我需要暂停使用 win32 API 的 CreateTimerQueueTimer 函数创建的计时器,但我找不到暂停计时器的方法。有人知道这是否可能吗? 最佳答案 相信你可以调用ChangeTimer
我的应用程序需要高分辨率(比 1 毫秒更准确)计时。 Windows 中的可等待计时器精确到(或可以精确到毫秒),但如果我需要精确的周期,比如 35.7142857141 毫秒,即使是 36 毫秒周期
我使用 Windows 多媒体 dll 创建了一个高分辨率计时器 timSetEvent() 但是timeSetEvent()页面推荐使用: CreateTimerQueueTimer() 如何使用
这个问题有点长,但我们开始吧。有一个 FormatDateTime 版本据说是线程安全的,因为您使用 GetLocaleFormatSettings(3081, FormatSettings); 获取
我正在努力实现 +/- 毫秒计时精度。我希望线程之间的时间为 10 毫秒,但当我测量时间时,我得到的结果接近 15 毫秒。 我想了解问题是由于我测量时间的方式引起的,还是我测量时间准确并且 Creat
我正在尝试使用 CreateTimerQueueTimer(...) 每隔一段时间运行一个函数。 我正在使用来自 MSDN 的示例,主要是这一行与我有关: CreateTimerQueueTimer(
我是一名优秀的程序员,十分优秀!