using System;
using System.Threading;
internal class TimerQueueTimer : IDisposable
{
public TimerQueueTimer(int interval, int msBeforeFirstCall)
{
this.interval = interval;
this.msBeforeFirstCall = msBeforeFirstCall;
this.callback = this.ticked;
this.isTheFirstTick = true;
this.isStopped = true;
}
public event EventHandler Ticked;
public void Start()
{
if (!this.isStopped)
{
return;
}
this.isTheFirstTick = true;
this.isStopped = false;
Computer.ChangeTimerResolutionTo(1);
NativeMethods.CreateTimerQueueTimer(
out this.handle,
IntPtr.Zero,
this.callback,
IntPtr.Zero,
(uint)this.msBeforeFirstCall,
(uint)this.interval,
CallbackExecution.ExecuteInTimerThread);
}
public void Stop()
{
if (this.isStopped)
{
return;
}
NativeMethods.DeleteTimerQueueTimer(
IntPtr.Zero,
this.handle,
IntPtr.Zero);
Computer.ClearTimerResolutionChangeTo(1);
this.isStopped = true;
}
public void Dispose()
{
this.Stop();
}
private void ticked(IntPtr parameterPointer, bool timerOrWaitFired)
{
if (this.isStopped)
{
return;
}
if (this.isTheFirstTick)
{
Thread.CurrentThread.Priority = ThreadPriority.Highest;
}
this.isTheFirstTick = false;
var ticked = this.Ticked;
if (ticked != null)
{
ticked(this, EventArgs.Empty);
}
}
private IntPtr handle;
private volatile bool isStopped;
private volatile bool isTheFirstTick;
private readonly WaitOrTimerDelegate callback;
private readonly int interval;
private readonly int msBeforeFirstCall;
}
(注意:Computer.ChangeTimerResolutionTo()
和Computer.ClearTimerResolutionChangeTo()
分别致电timeBeginPeriod
和timeEndPeriod
。)
问题:
Ticked
则提高tickCount % interval == 0
吗?较低的间隔计时器是否更准确和精确?timeSetEvent
计时器准确和/或精确?我问的原因是因为我们遇到了定时器回调问题,当系统负载很重时,偶尔会延迟最多约50ms。与我们以前使用timeSetEvent
时相比,我觉得这种情况发生的次数较少 - 尽管这可能只是一种幻觉。我知道Windows不是确定性的,所以我只能这么做。但是,我想确保我已尽我所能,尽可能地将其作为高优先级。还有什么我可以做的吗?
答案 0 :(得分:0)
我使用优先级队列来解决这个问题:队列的每个元素都包含回调地址(定时器例程),指向回调参数的指针以及将来应该触发的时间。
'time'是优先级,这里的逻辑是有可能从另一个线程唤醒定时器线程。当回调由另一个线程添加到队列时,定时器线程将被唤醒并且它寻找优先级队列的顶部元素,计算当前时间与存储在队列中的“时间”之间的差异并休眠直到计算的超时超过。
当超时唤醒定时器线程时,它从线程池启动新线程,调用回调。
我有一个计时器队列实现here,它没有经过良好测试,但你可以看看它是否有帮助。