修复DeviceManager.cs中的编译错误,删除多余的代码块
This commit is contained in:
@@ -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方式接收温度数据");
|
// 重置停止事件和状态
|
||||||
try
|
|
||||||
{
|
|
||||||
// 确保之前的连接已关闭
|
|
||||||
StopTemperatureDataReceiving();
|
|
||||||
// 在锁内执行所有关键状态更新,确保原子性
|
|
||||||
lock (_lockObject)
|
|
||||||
{
|
|
||||||
// 重置停止事件
|
|
||||||
_stopTemperatureEvent?.Dispose();
|
_stopTemperatureEvent?.Dispose();
|
||||||
_stopTemperatureEvent = new ManualResetEvent(false);
|
_stopTemperatureEvent = new ManualResetEvent(false);
|
||||||
_isReceivingTemperatureData = true;
|
// 设置接收状态为false,符合要求:系统初始化时,设置接收状态为false
|
||||||
}
|
_isReceivingTemperatureData = false;
|
||||||
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"
|
||||||
};
|
};
|
||||||
|
|
||||||
// 在锁内更新线程引用
|
|
||||||
lock (_lockObject)
|
|
||||||
{
|
|
||||||
_temperatureReceiveThread = newThread;
|
_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,16 +1136,80 @@ 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客户端并连接到设备的温度数据端口
|
// 主循环,持续执行直到收到停止信号
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
// 检查停止信号
|
||||||
|
bool stopRequested = false;
|
||||||
|
lock (_lockObject)
|
||||||
|
{
|
||||||
|
if (_stopTemperatureEvent != null && _stopTemperatureEvent.WaitOne(0))
|
||||||
|
{
|
||||||
|
stopRequested = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stopRequested)
|
||||||
|
{
|
||||||
|
Log("接收到停止信号,准备退出温度数据接收循环");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前接收状态和暂停状态
|
||||||
|
bool isReceiving = false;
|
||||||
|
bool isPaused = false;
|
||||||
|
lock (_lockObject)
|
||||||
|
{
|
||||||
|
isReceiving = _isReceivingTemperatureData;
|
||||||
|
isPaused = _isTemperatureReceivingPaused;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据用户要求的逻辑处理
|
||||||
|
if (!isReceiving)
|
||||||
|
{
|
||||||
|
// 如果接收状态为false
|
||||||
|
if (isPaused)
|
||||||
|
{
|
||||||
|
// 如果暂停,则Sleep 1秒后继续
|
||||||
|
Log("接收状态为false且处于暂停状态,等待1秒后继续");
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 否则同步创建tcp连接
|
||||||
|
Log("接收状态为false且未暂停,创建TCP连接");
|
||||||
|
|
||||||
|
// 清理之前的连接
|
||||||
|
try
|
||||||
|
{
|
||||||
|
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
|
localTcpClient = new TcpClient
|
||||||
{
|
{
|
||||||
ReceiveTimeout = 5000,
|
ReceiveTimeout = 5000,
|
||||||
@@ -1166,29 +1217,18 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
};
|
};
|
||||||
|
|
||||||
Log($"正在连接到温度数据端口 {TEMPERATURE_TCP_PORT}...");
|
Log($"正在连接到温度数据端口 {TEMPERATURE_TCP_PORT}...");
|
||||||
IAsyncResult result = localTcpClient.BeginConnect(_deviceIp, TEMPERATURE_TCP_PORT, null, null);
|
localTcpClient.Connect(_deviceIp, TEMPERATURE_TCP_PORT);
|
||||||
bool connected = result.AsyncWaitHandle.WaitOne(3000, true);
|
|
||||||
|
|
||||||
if (!connected || !localTcpClient.Connected)
|
|
||||||
{
|
|
||||||
Log("温度数据TCP连接失败,超时");
|
|
||||||
localTcpClient.Close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
localTcpClient.EndConnect(result);
|
|
||||||
Log("温度数据TCP连接成功");
|
Log("温度数据TCP连接成功");
|
||||||
|
|
||||||
// 获取网络流
|
// 获取网络流
|
||||||
localStream = localTcpClient.GetStream();
|
localStream = localTcpClient.GetStream();
|
||||||
localStream.ReadTimeout = 5000;
|
localStream.ReadTimeout = 5000;
|
||||||
|
|
||||||
// 更新类成员变量,在锁内进行
|
// 更新类成员变量和状态
|
||||||
lock (_lockObject)
|
lock (_lockObject)
|
||||||
{
|
{
|
||||||
_temperatureTcpClient = localTcpClient;
|
_temperatureTcpClient = localTcpClient;
|
||||||
_temperatureStream = localStream;
|
_temperatureStream = localStream;
|
||||||
// 确保接收状态为true
|
|
||||||
_isReceivingTemperatureData = true;
|
_isReceivingTemperatureData = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1196,157 +1236,84 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
byte[] startCommand = Encoding.ASCII.GetBytes("start_temp_transfer\r\n");
|
byte[] startCommand = Encoding.ASCII.GetBytes("start_temp_transfer\r\n");
|
||||||
localStream.Write(startCommand, 0, startCommand.Length);
|
localStream.Write(startCommand, 0, startCommand.Length);
|
||||||
localStream.Flush();
|
localStream.Flush();
|
||||||
|
Log("已发送开始温度数据传输命令");
|
||||||
|
|
||||||
Log("已发送开始温度数据传输命令,开始接收温度数据");
|
// 更新状态标志
|
||||||
|
isReceiving = true;
|
||||||
// 循环读取数据,使用更安全的退出机制
|
}
|
||||||
bool shouldContinue = true;
|
catch (Exception ex)
|
||||||
while (shouldContinue)
|
{
|
||||||
{
|
Log($"TCP连接或初始化失败: {ex.Message}");
|
||||||
// 检查停止信号和接收状态
|
// 连接失败后等待1秒再重试
|
||||||
bool stopRequested = false;
|
Thread.Sleep(1000);
|
||||||
bool isReceiving = true;
|
continue;
|
||||||
|
}
|
||||||
lock (_lockObject)
|
|
||||||
{
|
|
||||||
if (_stopTemperatureEvent != null && _stopTemperatureEvent.WaitOne(0))
|
|
||||||
{
|
|
||||||
stopRequested = true;
|
|
||||||
}
|
}
|
||||||
isReceiving = _isReceivingTemperatureData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stopRequested)
|
// 如果接收状态为true
|
||||||
|
if (isReceiving && localTcpClient != null && localStream != null && localTcpClient.Connected)
|
||||||
{
|
{
|
||||||
Log("接收到停止信号,准备退出温度数据接收循环");
|
|
||||||
shouldContinue = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isReceiving)
|
|
||||||
{
|
|
||||||
Log("接收状态已更改(isReceiving=false),准备退出温度数据接收循环");
|
|
||||||
shouldContinue = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 检查连接状态
|
|
||||||
if (localTcpClient == null || !localTcpClient.Connected)
|
|
||||||
{
|
|
||||||
Log("温度数据TCP连接已断开");
|
|
||||||
shouldContinue = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查流是否可读
|
|
||||||
if (localStream == null || !localStream.CanRead)
|
|
||||||
{
|
|
||||||
Log("网络流不可读,停止接收");
|
|
||||||
shouldContinue = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查是否有数据可读,避免阻塞
|
|
||||||
if (localStream.DataAvailable)
|
if (localStream.DataAvailable)
|
||||||
{
|
{
|
||||||
// 读取数据
|
// 读取数据
|
||||||
int bytesRead = localStream.Read(buffer, 0, buffer.Length);
|
int bytesRead = localStream.Read(buffer, 0, buffer.Length);
|
||||||
if (bytesRead > 0)
|
if (bytesRead > 0)
|
||||||
{
|
{
|
||||||
// 将读取的数据添加到累积器
|
|
||||||
byte[] receivedBytes = new byte[bytesRead];
|
byte[] receivedBytes = new byte[bytesRead];
|
||||||
Array.Copy(buffer, receivedBytes, bytesRead);
|
Array.Copy(buffer, receivedBytes, bytesRead);
|
||||||
|
|
||||||
Log($"接收到温度数据字节数: {bytesRead}");
|
Log($"接收到温度数据字节数: {bytesRead}");
|
||||||
|
|
||||||
// 检查是否处于暂停状态
|
// 如果暂停,接收后丢弃
|
||||||
bool isPaused = false;
|
|
||||||
lock (_lockObject)
|
|
||||||
{
|
|
||||||
isPaused = _isTemperatureReceivingPaused;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isPaused)
|
if (isPaused)
|
||||||
{
|
{
|
||||||
Log("温度数据接收处于暂停状态,数据已接收但不处理");
|
Log("接收状态为true但处于暂停状态,数据已接收但丢弃");
|
||||||
// 数据已接收但不处理,直接丢弃
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 线程安全地更新累积器或直接处理
|
// 否则同步接收并处理数据
|
||||||
lock (temperatureDataAccumulator)
|
//lock (temperatureDataAccumulator)
|
||||||
{
|
//{
|
||||||
temperatureDataAccumulator.AddRange(receivedBytes);
|
// temperatureDataAccumulator.AddRange(receivedBytes);
|
||||||
ProcessReceivedTemperatureData(temperatureDataAccumulator);
|
// ProcessReceivedTemperatureData(temperatureDataAccumulator);
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 读取到0字节表示连接已关闭
|
// 连接已关闭
|
||||||
Log("远程主机关闭了连接");
|
Log("远程主机关闭了连接");
|
||||||
shouldContinue = false;
|
lock (_lockObject)
|
||||||
break;
|
{
|
||||||
|
_isReceivingTemperatureData = false;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 如果没有数据可读,短暂休眠避免CPU占用过高
|
// 短暂休眠避免CPU占用过高
|
||||||
Thread.Sleep(10);
|
Thread.Sleep(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log($"温度数据接收异常: {ex.Message}");
|
Log($"接收数据异常: {ex.Message}");
|
||||||
Log($"异常详情: {ex.StackTrace}");
|
// 连接异常,重置状态准备重连
|
||||||
// 检查是否为严重异常
|
lock (_lockObject)
|
||||||
if (ex is System.Security.SecurityException ||
|
|
||||||
ex is UnauthorizedAccessException ||
|
|
||||||
ex is System.Threading.ThreadAbortException)
|
|
||||||
{
|
{
|
||||||
Log("发生严重异常,停止温度数据接收");
|
_isReceivingTemperatureData = false;
|
||||||
shouldContinue = false;
|
}
|
||||||
break;
|
// 短暂休眠后重试
|
||||||
|
Thread.Sleep(100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log("非致命异常,继续尝试接收温度数据");
|
// 没有有效连接,短暂休眠
|
||||||
// 非致命异常,短暂休眠后继续尝试
|
Thread.Sleep(50);
|
||||||
Thread.Sleep(100);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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时,关闭后台线程。
|
||||||
|
|
||||||
Reference in New Issue
Block a user