修复温度数据接收连接状态检查和自动重连机制

This commit is contained in:
zqm
2025-10-31 14:41:37 +08:00
parent 4950d731eb
commit 31178ec991

View File

@@ -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}");
}
}
}
}