我能不能使这个TimerQueueTimer 类的性能更高
本文关键字:性能 TimerQueueTimer 能不能 | 更新日期: 2023-09-27 17:56:09
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
。
问题:
- 回调在计时器的线程中运行,而不是在 ThreadPool 线程中运行。 只要回调函数速度快就可以了,对吧?
- 将回调线程(以及计时器线程)优先级设置为"最高"是否在性能方面有任何作用?
- 如果
tickCount % interval == 0
,是否最好使计时器间隔为 1ms 并计算滴答声,提高Ticked
? 间隔较低的计时器是否更准确和精确? - 是否有任何原因可能不如类似创建的
timeSetEvent
计时器准确和/或精确?
我问的原因是,当系统负载过重时,我们遇到了计时器回调偶尔延迟长达~50ms的问题。 与我们以前使用timeSetEvent
时相比,感觉这种情况发生的频率更低了——尽管这可能只是一种错觉。 我知道Windows不是确定性的,所以我能做的只有这么多。 但是,我想确保我已经尽我所能使它尽可能高优先级。 我还能做什么吗?
我使用优先级队列来解决这个问题:队列的每个元素都包含回调地址(计时器例程),指向回调参数的指针以及将来应该触发的时间。
"时间"是优先级,这里的逻辑是有可能从另一个线程唤醒计时器线程。当另一个线程将回调添加到队列中时,计时器线程将唤醒并查找优先级队列的顶部元素,计算当前时间和存储在队列中的"时间"之间的差异,并休眠,直到超过计算的超时。
当计时器线程因超时而被唤醒时,它会从线程池启动新线程,从而调用回调。
我这里有一个计时器队列实现,它没有经过很好的测试,但您可以查看它是否有帮助。