我创建了一个看门狗定时器(使用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);
}
}
主代码调用Go()
,然后在每次收到数据包时调用Reset()
。如果计时器到期,则调用OnTimerExpired()
。
由于每秒可能有数百个数据包接收,并且由于应用程序的主要工作是响应此类数据包,因此我开始怀疑重置计时器是否过于CPU / OS密集。< / p>
任何想法如何以这种方式调用Timer.Stop()/Timer.Start()
可能会影响性能(就延迟而言)?
答案 0 :(得分:5)
使用简单的时间跨度或整数变量作为标志。当计时器滴答时,它会检查一个Stopwatch对象,以查看自该标志最后一次更新以来经过了多长时间。如果它超过你的超时值,你就会触发看门狗代码。
现在,当新数据包进入时,其他代码可以使用秒表更新您的时间跨度标志值,而不是重置您的计时器。
您还应该将计时器的滴答间隔设置为您希望实际超时持续时间的1/2,或者在事件中设置代码来设置您的间隔,以便您的下一个滴答事件仅在您之后的几毫秒如果连接现在被切断,将会超时。否则,在最后一个数据包在嘀嗒事件发生后很快到达的情况下,你最终可能会等待超过两倍的时间。
答案 1 :(得分:2)
顺便说一下,另一个选项就是只要有一个Boolean
标志,只要有消息进入就会设置该标志。定时器事件处理程序会检查该标志并在没有设置时发出警告。所以你有:
private bool GotAMessage = false;
void MessageReceived()
{
// happens whenever a message is received
GotAMessage = true;
}
void OnTimerExpired(object state)
{
if (!GotAMessage)
{
// didn't receive a message in time.
}
GotAMessage = false;
}
答案 2 :(得分:1)
更简单的选项是调用WatchDog类上的方法,该方法更新接收数据包的公共lastPacketReceived值时间。然后你只需要在WatchDog类中启动一次计时器,每个超时间隔打一次,并将当前时间与lastPacketReceived值进行比较:
public static class WatchDog
{
static object locker = new object();
static long lastPacketReceived;
static Stopwatch stopWatch = new Stopwatch();
static long threshold = 5000;
static WatchDog()
{
Timer watchDogTimer = new Timer(1000);
watchDogTimer.Elapsed += new ElapsedEventHandler(watchDogTimer_Elapsed);
watchDogTimer.Start();
stopWatch.Start();
}
static void watchDogTimer_Elapsed(object sender, ElapsedEventArgs e)
{
lock (locker)
{
if ((stopWatch.ElapsedMilliseconds - lastPacketReceived) > threshold)
{
// threshold exceeded
}
}
}
public static void PacketReceived()
{
lock (locker)
{
lastPacketReceived = stopWatch.ElapsedMilliseconds;
}
}
}
答案 3 :(得分:0)
任何想法如何调用
Timer.Stop()
/Timer.Start()
这种方式可能会影响性能(就延迟而言)?
<强>无强>
不太可能测量执行此操作所需的资源量。除非遇到性能问题,否则不要尝试解决性能问题,至少要使用软件来分析软件,看看它是否存在实际问题。