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计时器更不准确和/或精确?我之所以问这个问题,是因为我们遇到了计时器回调的问题,当系统负载很重时,计时器回调偶尔会被延迟多达50 is。与我们以前使用timeSetEvent时相比,感觉这种情况发生的频率要低一些--尽管这可能只是一种幻觉。我知道Windows不是确定性的,所以我只能做这么多。然而,我想确保我已经做了我能做的一切,使这尽可能高优先。还有什么我能做的吗?
发布于 2014-01-28 16:34:16
我使用优先级队列来解决这个问题:队列中的每个元素都包含回调地址(计时器例程),指向回调参数的指针,以及将来应该触发的时间。
“时间”是优先级,这里的逻辑是有可能从另一个线程唤醒计时器线程。当回调被另一个线程添加到队列中时,计时器线程将被唤醒并查找优先级队列的顶部元素,计算存储在队列中的当前时间和“时间”之间的差异,直到计算的超时超过为止。
当计时器线程被超时唤醒时,它从调用回调的线程池中启动新线程。
我有一个计时器队列实现这里,它没有经过很好的测试,但您可以查看它是否有用。
https://stackoverflow.com/questions/5959484
复制相似问题