修复DeviceManager.cs中的编译错误,删除多余的代码块

This commit is contained in:
zqm
2025-10-31 17:02:03 +08:00
parent be0696663a
commit eeb4615b27
2 changed files with 157 additions and 236 deletions

View File

@@ -890,28 +890,18 @@ namespace JoyD.Windows.CS.Toprie
return;
}
// 添加额外的状态检查,避免不必要的重复启动
if (_isReceivingTemperatureData && _temperatureReceiveThread != null && _temperatureReceiveThread.IsAlive)
// 避免重复启动
if (_temperatureReceiveThread != null && _temperatureReceiveThread.IsAlive)
{
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] StartTemperatureDataReceiving() - 温度数据接收已经在行中,避免重复启动");
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] StartTemperatureDataReceiving() - 温度数据接收线程已经在行中,避免重复启动");
return;
}
}
Log("开始使用TCP方式接收温度数据");
try
{
// 确保之前的连接已关闭
StopTemperatureDataReceiving();
// 在锁内执行所有关键状态更新,确保原子性
lock (_lockObject)
{
// 重置停止事件
_stopTemperatureEvent?.Dispose();
_stopTemperatureEvent = new ManualResetEvent(false);
_isReceivingTemperatureData = true;
}
Thread.Sleep(500);
// 重置停止事件和状态
_stopTemperatureEvent?.Dispose();
_stopTemperatureEvent = new ManualResetEvent(false);
// 设置接收状态为false符合要求系统初始化时设置接收状态为false
_isReceivingTemperatureData = false;
// 创建并启动温度数据接收线程
Thread newThread = new Thread(ReceiveTemperatureDataWithTcp)
@@ -920,32 +910,29 @@ namespace JoyD.Windows.CS.Toprie
Name = "TemperatureReceiveThread"
};
// 在锁内更新线程引用
lock (_lockObject)
{
_temperatureReceiveThread = newThread;
}
_temperatureReceiveThread = newThread;
}
Log("开始使用TCP方式接收温度数据");
try
{
// 启动线程
newThread.Start();
_temperatureReceiveThread.Start();
}
catch (Exception ex)
{
// 记录异常
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] StartTemperatureDataReceiving() - 异常: {ex.Message}");
// 在异常情况下确保状态正确重置
lock (_lockObject)
{
_isReceivingTemperatureData = false;
_temperatureReceiveThread = null;
}
// 如果连接状态异常,触发异常事件
OnConnectionException(new ConnectionExceptionEventArgs(ex, "启动温度数据接收失败"));
}
finally
{
// 确保方法执行完成时记录日志
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] StartTemperatureDataReceiving() - 执行完成");
}
}
@@ -1149,205 +1136,185 @@ namespace JoyD.Windows.CS.Toprie
{
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] ReceiveTemperatureDataWithTcp() - 开始执行");
// 使用局部变量存储资源避免在finally中访问可能已被释放的字段
// 使用局部变量存储资源
TcpClient localTcpClient = null;
NetworkStream localStream = null;
List<byte> temperatureDataAccumulator = new List<byte>();
// 根据分析温度数据帧大小为98313字节(9字节头部+256×192×2字节数据),增大缓冲区提高接收效率
byte[] buffer = new byte[65536]; // 增大温度数据缓冲区减少Read操作次数
byte[] buffer = new byte[65536]; // 缓冲区大小
try
{
// 创建TCP客户端并连接到设备的温度数据端口
localTcpClient = new TcpClient
// 主循环,持续执行直到收到停止信号
while (true)
{
ReceiveTimeout = 5000,
SendTimeout = 5000
};
Log($"正在连接到温度数据端口 {TEMPERATURE_TCP_PORT}...");
IAsyncResult result = localTcpClient.BeginConnect(_deviceIp, TEMPERATURE_TCP_PORT, null, null);
bool connected = result.AsyncWaitHandle.WaitOne(3000, true);
if (!connected || !localTcpClient.Connected)
{
Log("温度数据TCP连接失败超时");
localTcpClient.Close();
return;
}
localTcpClient.EndConnect(result);
Log("温度数据TCP连接成功");
// 获取网络流
localStream = localTcpClient.GetStream();
localStream.ReadTimeout = 5000;
// 更新类成员变量,在锁内进行
lock (_lockObject)
{
_temperatureTcpClient = localTcpClient;
_temperatureStream = localStream;
// 确保接收状态为true
_isReceivingTemperatureData = true;
}
// 发送开始温度数据传输的命令
byte[] startCommand = Encoding.ASCII.GetBytes("start_temp_transfer\r\n");
localStream.Write(startCommand, 0, startCommand.Length);
localStream.Flush();
Log("已发送开始温度数据传输命令,开始接收温度数据");
// 循环读取数据,使用更安全的退出机制
bool shouldContinue = true;
while (shouldContinue)
{
// 检查停止信号和接收状态
// 检查停止信号
bool stopRequested = false;
bool isReceiving = true;
lock (_lockObject)
{
if (_stopTemperatureEvent != null && _stopTemperatureEvent.WaitOne(0))
{
stopRequested = true;
}
isReceiving = _isReceivingTemperatureData;
}
if (stopRequested)
{
Log("接收到停止信号,准备退出温度数据接收循环");
shouldContinue = false;
break;
}
// 获取当前接收状态和暂停状态
bool isReceiving = false;
bool isPaused = false;
lock (_lockObject)
{
isReceiving = _isReceivingTemperatureData;
isPaused = _isTemperatureReceivingPaused;
}
// 根据用户要求的逻辑处理
if (!isReceiving)
{
Log("接收状态已更改(isReceiving=false),准备退出温度数据接收循环");
shouldContinue = false;
break;
}
try
{
// 检查连接状态
if (localTcpClient == null || !localTcpClient.Connected)
// 如果接收状态为false
if (isPaused)
{
Log("温度数据TCP连接已断开");
shouldContinue = false;
break;
// 如果暂停则Sleep 1秒后继续
Log("接收状态为false且处于暂停状态等待1秒后继续");
Thread.Sleep(1000);
continue;
}
// 检查流是否可读
if (localStream == null || !localStream.CanRead)
else
{
Log("网络流不可读,停止接收");
shouldContinue = false;
break;
}
// 检查是否有数据可读,避免阻塞
if (localStream.DataAvailable)
{
// 读取数据
int bytesRead = localStream.Read(buffer, 0, buffer.Length);
if (bytesRead > 0)
// 否则同步创建tcp连接
Log("接收状态为false且未暂停创建TCP连接");
// 清理之前的连接
try
{
// 将读取的数据添加到累积器
byte[] receivedBytes = new byte[bytesRead];
Array.Copy(buffer, receivedBytes, bytesRead);
if (localStream != null)
{
localStream.Close();
localStream = null;
}
if (localTcpClient != null)
{
localTcpClient.Close();
localTcpClient = null;
}
}
catch (Exception ex)
{
Log($"关闭旧连接异常: {ex.Message}");
}
try
{
// 创建TCP客户端并连接
localTcpClient = new TcpClient
{
ReceiveTimeout = 5000,
SendTimeout = 5000
};
Log($"接到温度数据字节数: {bytesRead}");
// 检查是否处于暂停状态
bool isPaused = false;
lock (_lockObject)
{
isPaused = _isTemperatureReceivingPaused;
}
Log($"正在连接到温度数据端口 {TEMPERATURE_TCP_PORT}...");
localTcpClient.Connect(_deviceIp, TEMPERATURE_TCP_PORT);
Log("温度数据TCP连接成功");
// 获取网络流
localStream = localTcpClient.GetStream();
localStream.ReadTimeout = 5000;
// 更新类成员变量和状态
lock (_lockObject)
{
_temperatureTcpClient = localTcpClient;
_temperatureStream = localStream;
_isReceivingTemperatureData = true;
}
// 发送开始温度数据传输的命令
byte[] startCommand = Encoding.ASCII.GetBytes("start_temp_transfer\r\n");
localStream.Write(startCommand, 0, startCommand.Length);
localStream.Flush();
Log("已发送开始温度数据传输命令");
// 更新状态标志
isReceiving = true;
}
catch (Exception ex)
{
Log($"TCP连接或初始化失败: {ex.Message}");
// 连接失败后等待1秒再重试
Thread.Sleep(1000);
continue;
}
}
}
// 如果接收状态为true
if (isReceiving && localTcpClient != null && localStream != null && localTcpClient.Connected)
{
try
{
if (localStream.DataAvailable)
{
// 读取数据
int bytesRead = localStream.Read(buffer, 0, buffer.Length);
if (bytesRead > 0)
{
byte[] receivedBytes = new byte[bytesRead];
Array.Copy(buffer, receivedBytes, bytesRead);
Log($"接收到温度数据字节数: {bytesRead}");
// 如果暂停,接收后丢弃
if (isPaused)
{
Log("温度数据接收处于暂停状态,数据已接收但不处理");
// 数据已接收但不处理,直接丢弃
Log("接收状态为true但处于暂停状态,数据已接收但丢弃");
}
else
{
// 线程安全地更新累积器或直接处理
lock (temperatureDataAccumulator)
{
temperatureDataAccumulator.AddRange(receivedBytes);
ProcessReceivedTemperatureData(temperatureDataAccumulator);
}
// 否则同步接收并处理数据
//lock (temperatureDataAccumulator)
//{
// temperatureDataAccumulator.AddRange(receivedBytes);
// ProcessReceivedTemperatureData(temperatureDataAccumulator);
//}
}
}
else
{
// 连接已关闭
Log("远程主机关闭了连接");
lock (_lockObject)
{
_isReceivingTemperatureData = false;
}
continue;
}
}
else
{
// 读取到0字节表示连接已关闭
Log("远程主机关闭了连接");
shouldContinue = false;
break;
// 短暂休眠避免CPU占用过高
Thread.Sleep(10);
}
}
else
catch (Exception ex)
{
// 如果没有数据可读短暂休眠避免CPU占用过高
Thread.Sleep(10);
Log($"接收数据异常: {ex.Message}");
// 连接异常,重置状态准备重连
lock (_lockObject)
{
_isReceivingTemperatureData = false;
}
// 短暂休眠后重试
Thread.Sleep(100);
}
}
catch (TimeoutException)
else
{
// 超时异常,继续尝试读取
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)
@@ -1362,14 +1329,11 @@ namespace JoyD.Windows.CS.Toprie
lock (_lockObject)
{
_isReceivingTemperatureData = false;
// 不在这里调用StopTemperatureDataReceiving避免递归调用和潜在死锁
// 由调用者负责调用StopTemperatureDataReceiving
// 记录线程结束信息
Log($"温度数据接收线程已结束,重置相关状态");
_temperatureStream = null;
_temperatureTcpClient = null;
}
// 清理局部资源
// 清理资源
try
{
if (localStream != null)
@@ -1388,50 +1352,7 @@ 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}");
}
}
Log("温度数据接收线程已结束,重置相关状态");
}
}

View File

@@ -23,7 +23,7 @@
### Tcp温度数据接收
1. 系统初始化时,创建后台线程。
2. 设置接收状态为false,然后线程循环执行
3. 如果接收状态为false,如果暂停则Sleep 1秒后继续,否则同步创建tcp连接并同步接收和处理数据。
4. 如果接收状态为true,如果暂停,接收后丢弃。否则同步接收并处理数据。
4. Dispose时关闭后台线程。
3. 如果接收状态为false,{如果暂停则Sleep 1秒后继续,否则同步创建tcp连接并同步接收和处理数据。}
4. 如果接收状态为true,{如果暂停,接收后丢弃。否则同步接收并处理数据。}
5. Dispose时关闭后台线程。