我有一个客户端 - 服务器应用程序,我想定期检查客户端是否与服务器断开连接。
我已决定检查传入的数据包。如果我在15秒的时间内收到任何有效的连接, 如果没有,我已断开连接并尝试重新连接。
到目前为止,我有这个示例代码(这是从我的代码重新创建的示例):
viewDidLayoutSubviews
我想要的代码是:每次数据包到达时都会执行函数namespace TimerExample
{
class Program
{
static void Main(string[] args)
{
HandlePackets();
}
public void HandlePackets()
{
//code that handles incomming packets
foo test = new foo();
test.StartThread();
}
}
class foo
{
public bool _isRunning { get; set; }
private Stopwatch sw { get; set; }
public void StartThread()
{
this._isRunning = true;
new Thread(new ThreadStart(this.DoWork)).Start();
this.sw.Restart();
}
public void StopThread()
{
this._isRunning = false;
this.sw.Stop();
}
private void DoWork()
{
while (this._isRunning)
{
Console.WriteLine("Elapsed in miliseconds: " + this.GetRuntime().ToString());
if (GetRuntime() > 15000)
{
Console.WriteLine("Client disconnected.... restarting");
this.StopThread();
}
Thread.Sleep(1000);
}
}
public long GetRuntime()
{
return this.sw.ElapsedMilliseconds;
}
public foo()
{
_isRunning = false;
sw = new Stopwatch();
}
}
}
。在这个功能里面我会打电话
函数HandlePackets
将在单独的线程中运行StartThread
,此过程将持续Stopwatch
经过的时间(以毫秒为单位)
不会比15秒钟更大。
如果可以,我会致电stopwatch
。
所以基本上定时器会在每次收到数据包时重新启动,如果Reconnect
大于15秒,则会调用重新连接。
答案 0 :(得分:1)
有几种方法可以实现这种机制。
创建线程是最糟糕的。 注意 - 从多个线程访问Stopwatch实例成员是不安全的。
一个简单直接的解决方案是创建ThreadPool Timer
,让我们每隔15秒说一次,并通过Volatile.Read
检查布尔变量。一旦布尔变量为False - 您就可以重新连接。
从接收器线程,你只需要使用Volatile.Write
设置变量true。接收(几乎)时不会消耗资源。
在许多实现中可能是竞争,因为重新连接机制可以在新数据包到达之前启动片刻。最简单和最流氓的方法是在决定重新连接之前立即停止计时器,并在连接完成后再次启动计时器。您必须明白,没有办法解决这种错误重新连接问题。
上述方法非常类似于WatchDog
从设计角度来看,我建议您创建类:Receiver和WatchDog以及ConnectionManager
// Receives and processes data
class Receiver : IDisposable
{
public Receiver(WatchDog watchDog);
public void LoopReceive(); // Tick watch dog on every packet
public void Dispose();
}
// Setups timer and periodically checks if receiver is alive.
// If its not, it asks manager to reconnect and disposes receiver
class WatchDog : IDisposable
{
public WatchDog(ConnectionFactory factory);
// Setups timer, performs Volatile.Read and if receiver is dead, call dispose on it and ask manager to reconnect.
public void StartWatching(IDisposable subject);
public void Tick(); // Volatile.Write
public void Dispose();
}
// Can re-connect and create new instances of timer and watchdog
// Holds instance variable of receiver created
class ConnectionManager
{
public void Connect();
// disposes watch dog and calls connect
public void ReConnect(WatchDog watchDog);
}
PS:Volatile。*可以用标志变量
的volatile关键字替换