秒表在单独的线程重启
本文关键字:线程 重启 单独 | 更新日期: 2023-09-27 18:01:18
我有一个客户端-服务器应用程序,我想定期检查客户端是否与服务器断开连接。
我已经决定检查传入的数据包。如果我在15秒的时间范围内收到任何消息,我就有一个有效的连接,如果没有,我已断开连接,将尝试重新连接。
到目前为止,我有这个示例代码(这是从我的代码重新创建的示例):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
,并且只要stopwatch
经过的时间以毫秒为单位,此进程将继续进行不会超过15秒。
如果它会,我会调用Reconnect
。
所以基本上每次收到数据包时timer都会重新启动,如果ElapsedTime
大于15秒,则会调用reconnect。
有几种方法可以实现此机制。
创建线程是最糟糕的。注意,从多个线程访问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:波动。对于标志变量