StopWatch在单独的线程重启中

时间:2015-07-07 11:51:20

标签: c# multithreading timer packet stopwatch

我有一个客户端 - 服务器应用程序,我想定期检查客户端是否与服务器断开连接。

我已决定检查传入的数据包。如果我在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秒,则会调用重新连接。

1 个答案:

答案 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关键字替换