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

View File

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