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