密集停止/启动C#计时器

bav*_*aza 4 c# performance timer

我已经创建了一个看门狗定时器(使用System.Windows.Forms.Timer),如果很长一段时间到期而没有收到一小段数据,就会触发:

using System.Windows.Forms;
public class Watchdog
{
    private Timer Timer;

    public void Go()
    {
        Timer.Start();
    }

    public void Reset()
    {
        Timer.Stop();
        Timer.Start();
    }

    private void OnTimerExpired(object State)
    {
        Timer.Stop();
        DoSomething();
    }

    public Watchdog()
    {
        Timer = new Timer();
        Timer.Tick += new EventHandler(OnTimerExpired);
        Timer.Interval = (1000 * Timeout);            
    }
}
Run Code Online (Sandbox Code Playgroud)

主代码调用Go(),然后Reset()每次收到数据包时调用.如果计时器到期,OnTimerExpired()则调用.

由于每秒可能有数百个数据包接收,并且由于应用程序的主要工作是响应此类数据包,因此我开始怀疑重置计时器是否过于CPU/OS密集型.

任何想法如何调用Timer.Stop()/Timer.Start()这种方式可能会影响性能(就延迟而言)?

Joe*_*orn 5

使用简单的时间跨度或整数变量作为标志.当计时器滴答时,它会检查一个Stopwatch对象,以查看自该标志最后一次更新以来经过了多长时间.如果它超过你的超时值,你会触发看门狗代码.

现在,当新数据包进入时,其他代码可以使用秒表来更新您的时间跨度标志值,而不是重置您的计时器.

您还应该将计时器的滴答间隔设置为您希望实际超时持续时间的1/2,或者在事件中设置代码以设置您的间隔,以便您的下一个滴答事件在您超时后的几毫秒内连接现在被切断了.否则,在最后一个数据包在tick事件发生后很快到达的情况下,你最终可能会等待超过两倍的超时持续时间.

  • 不要为此使用`DateTime`!您将在夏令时转换期间遇到问题,以及用户是否更改时钟。最好在程序启动时启动“秒表”,并在每次收到消息时保存其“已用”值。然后计时器滴答可以将当前“已用”值与上次收到的消息值进行比较。 (2认同)