修复温度数据接收连接状态检查和自动重连机制
This commit is contained in:
@@ -1086,7 +1086,11 @@ namespace JoyD.Windows.CS.Toprie
|
||||
TcpClient localTcpClient = null;
|
||||
NetworkStream localStream = null;
|
||||
List<byte> temperatureDataAccumulator = new List<byte>();
|
||||
byte[] buffer = new byte[8192]; // 温度数据缓冲区
|
||||
// 根据分析,温度数据帧大小为98313字节(9字节头部+256×192×2字节数据),增大缓冲区提高接收效率
|
||||
byte[] buffer = new byte[65536]; // 增大温度数据缓冲区,减少Read操作次数
|
||||
|
||||
// 心跳检查时间记录,用于定期验证连接有效性
|
||||
DateTime lastConnectionCheckTime = DateTime.Now;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -1213,26 +1217,82 @@ namespace JoyD.Windows.CS.Toprie
|
||||
// 如果没有数据可读,短暂休眠避免CPU占用过高
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
|
||||
// 定期检查连接状态,确保连接仍然有效
|
||||
if (DateTime.Now - lastConnectionCheckTime > TimeSpan.FromSeconds(30))
|
||||
{
|
||||
Log("定期检查温度数据连接状态");
|
||||
// 尝试发送一个简单的心跳消息到TCP连接
|
||||
try
|
||||
{
|
||||
if (localStream != null && localStream.CanWrite)
|
||||
{
|
||||
byte[] heartbeat = Encoding.ASCII.GetBytes("heartbeat\r\n");
|
||||
localStream.Write(heartbeat, 0, heartbeat.Length);
|
||||
localStream.Flush();
|
||||
Log("温度数据连接心跳发送成功");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"温度数据连接心跳发送失败: {ex.Message},可能需要重新连接");
|
||||
}
|
||||
lastConnectionCheckTime = DateTime.Now;
|
||||
}
|
||||
}
|
||||
catch (TimeoutException)
|
||||
{
|
||||
// 超时异常,继续尝试读取
|
||||
Log("温度数据接收超时,继续尝试");
|
||||
// 短暂休眠后重试,避免CPU占用过高
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
Log($"温度数据接收IO异常: {ex.Message}");
|
||||
// 对于网络中断异常,尝试重新连接而不是直接退出
|
||||
// 在.NET Framework 4.0中,HResult是受保护的,我们通过消息内容来判断
|
||||
string exceptionMessage = ex.Message.ToLower();
|
||||
if (exceptionMessage.Contains("远程主机") ||
|
||||
exceptionMessage.Contains("强制关闭") ||
|
||||
exceptionMessage.Contains("connection") ||
|
||||
exceptionMessage.Contains("closed"))
|
||||
{
|
||||
Log("检测到网络连接异常,准备重新连接");
|
||||
// 短暂休眠后允许循环退出,让外层逻辑处理重连
|
||||
Thread.Sleep(100);
|
||||
shouldContinue = false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("非致命IO异常,继续尝试接收");
|
||||
// 短暂休眠后继续尝试
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"温度数据接收异常: {ex.Message}");
|
||||
Log($"异常详情: {ex.StackTrace}");
|
||||
// 检查是否为严重异常
|
||||
if (ex is System.Security.SecurityException ||
|
||||
ex is UnauthorizedAccessException ||
|
||||
ex is System.Threading.ThreadAbortException)
|
||||
{
|
||||
Log("发生严重异常,停止温度数据接收");
|
||||
shouldContinue = false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("非致命异常,继续尝试接收温度数据");
|
||||
// 非致命异常,短暂休眠后继续尝试
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] ReceiveTemperatureDataWithTcp() - 严重异常: {ex.Message}");
|
||||
@@ -1247,6 +1307,9 @@ namespace JoyD.Windows.CS.Toprie
|
||||
_isReceivingTemperatureData = false;
|
||||
// 不在这里调用StopTemperatureDataReceiving,避免递归调用和潜在死锁
|
||||
// 由调用者负责调用StopTemperatureDataReceiving
|
||||
|
||||
// 记录线程结束信息
|
||||
Log($"温度数据接收线程已结束,重置相关状态");
|
||||
}
|
||||
|
||||
// 清理局部资源
|
||||
@@ -1267,6 +1330,51 @@ namespace JoyD.Windows.CS.Toprie
|
||||
}
|
||||
}
|
||||
catch {}
|
||||
|
||||
// 重置类成员变量中的流和客户端引用
|
||||
lock (_lockObject)
|
||||
{
|
||||
_temperatureStream = null;
|
||||
_temperatureTcpClient = null;
|
||||
}
|
||||
|
||||
// 检查是否需要自动重新启动温度数据接收
|
||||
// 只有当设备仍在连接状态且用户没有明确停止时才尝试重连
|
||||
bool shouldAutoReconnect = false;
|
||||
lock (_lockObject)
|
||||
{
|
||||
// 检查是否有显式的停止信号
|
||||
bool hasStopSignal = _stopTemperatureEvent != null && _stopTemperatureEvent.WaitOne(0);
|
||||
// 如果没有停止信号且设备应该处于连接状态,则尝试重连
|
||||
shouldAutoReconnect = !hasStopSignal && _connectionStatus == ConnectionStatus.Connected;
|
||||
}
|
||||
|
||||
if (shouldAutoReconnect)
|
||||
{
|
||||
Log("检测到温度数据接收线程异常退出,准备自动重连");
|
||||
try
|
||||
{
|
||||
// 短暂延迟后尝试重新启动温度数据接收
|
||||
Thread.Sleep(2000);
|
||||
// 确保在新线程中启动,避免递归调用
|
||||
ThreadPool.QueueUserWorkItem(state =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Log("开始自动重新启动温度数据接收...");
|
||||
StartTemperatureDataReceiving();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"自动重连温度数据接收失败: {ex.Message}");
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"调度温度数据自动重连失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user