C# 我可以让这个TimerQueueTimer类更有效吗?
(注意:C# 我可以让这个TimerQueueTimer类更有效吗?,c#,performance,timer,C#,Performance,Timer,(注意:Computer.changeTimerSolutionTo()和Computer.cleartimerSolutionChangeTo()分别调用timeBeginPeriod和timeEndPeriod) 问题: 回调正在计时器的线程中运行,而不是在线程池线程中运行。只要回调函数是快速的,就可以了,对吗 将回调线程(以及计时器线程)的优先级设置为最高会对性能产生影响吗 如果tickCount%interval==0,那么将计时器间隔设为1ms并计数滴答声,提高Ticked是否更好?低
Computer.changeTimerSolutionTo()
和Computer.cleartimerSolutionChangeTo()
分别调用timeBeginPeriod
和timeEndPeriod
)
问题:
tickCount%interval==0,那么将计时器间隔设为1ms并计数滴答声,提高Ticked
是否更好?低间隔计时器是否更精确
timeSetEvent
计时器我问这个问题的原因是,当系统处于重载状态时,计时器回调偶尔会被延迟50毫秒。与我们之前使用的
timeSetEvent
相比,这种情况似乎不太常见——尽管这可能只是一种幻觉。我知道Windows不是确定性的,所以我只能做这么多。然而,我想确保我已经尽了我所能,使这个尽可能高的优先级。还有什么我可以做的吗?我使用优先级队列来解决这个问题:队列的每个元素都包含回调地址(计时器例程)、指向回调参数的指针以及将来应该触发它的时间
“时间”是优先级,这里的逻辑是有可能从另一个线程唤醒计时器线程。当回调被另一个线程添加到队列中时,计时器线程将被唤醒,它将查找优先级队列的顶部元素,计算当前时间和队列中存储的“时间”之间的差值,并休眠,直到计算的超时超过
当计时器线程被超时唤醒时,它从调用回调的线程池启动新线程
我有一个计时器队列实现,它没有经过很好的测试,但您可以看看它是否有帮助。仅供参考:首先检查
ticked==null
,只直接调用ticked
事件,这并不是最好的做法。通常,局部变量的全部要点是避免竞争条件。@如果您认为我解决了您的问题,则可以删除-ve point,这将是非常好的选择:)感谢@ruffp编辑并使答案更具可读性。今后,我将确保给出明确的答案。
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;
}