优化温度数据接收逻辑,修复端口号并增强线程安全性
This commit is contained in:
@@ -506,7 +506,23 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
Console.WriteLine("Camera开始使用HTTP方式接收图像");
|
Console.WriteLine("Camera开始使用HTTP方式接收图像");
|
||||||
// 直接调用HTTP方式的图像接收
|
// 直接调用HTTP方式的图像接收
|
||||||
_deviceManager.StartImageReceiving();
|
_deviceManager.StartImageReceiving();
|
||||||
_deviceManager.StartTemperatureDataReceiving();
|
|
||||||
|
// 在调用StartTemperatureDataReceiving前先调用StopTemperatureDataReceiving,保持与ResumeDetection方法一致的模式
|
||||||
|
// 并添加时间间隔检查,避免短时间内频繁调用
|
||||||
|
lock (_temperatureCallLock)
|
||||||
|
{
|
||||||
|
TimeSpan elapsed = DateTime.Now - _lastTemperatureStartCall;
|
||||||
|
if (elapsed.TotalMilliseconds < 500) // 至少间隔500毫秒
|
||||||
|
{
|
||||||
|
Console.WriteLine("避免短时间内重复启动温度数据接收,跳过本次调用");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_deviceManager.StopTemperatureDataReceiving();
|
||||||
|
_deviceManager.StartTemperatureDataReceiving();
|
||||||
|
_lastTemperatureStartCall = DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
||||||
_isReceivingImage = true;
|
_isReceivingImage = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -539,6 +555,9 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
}
|
}
|
||||||
|
|
||||||
private bool _isPaused = false; // 暂停状态标志
|
private bool _isPaused = false; // 暂停状态标志
|
||||||
|
// 记录上次启动温度数据接收的时间,用于防止短时间内重复调用
|
||||||
|
private DateTime _lastTemperatureStartCall = DateTime.MinValue;
|
||||||
|
private readonly object _temperatureCallLock = new object();
|
||||||
|
|
||||||
// Ping相关字段
|
// Ping相关字段
|
||||||
private System.Threading.Timer _pingTimer;
|
private System.Threading.Timer _pingTimer;
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
private NetworkStream _temperatureStream;
|
private NetworkStream _temperatureStream;
|
||||||
private bool _isReceivingTemperatureData = false;
|
private bool _isReceivingTemperatureData = false;
|
||||||
private ManualResetEvent _stopTemperatureEvent;
|
private ManualResetEvent _stopTemperatureEvent;
|
||||||
private const int TEMPERATURE_TCP_PORT = 7682; // 温度数据TCP端口
|
private const int TEMPERATURE_TCP_PORT = 8081; // 温度数据TCP端口 - 修正为热像仪SDK文档中指定的端口
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 项目路径属性
|
/// 项目路径属性
|
||||||
@@ -888,6 +888,13 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] StartTemperatureDataReceiving() - 连接未建立,无法开始温度数据接收");
|
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] StartTemperatureDataReceiving() - 连接未建立,无法开始温度数据接收");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加额外的状态检查,避免不必要的重复启动
|
||||||
|
if (_isReceivingTemperatureData && _temperatureReceiveThread != null && _temperatureReceiveThread.IsAlive)
|
||||||
|
{
|
||||||
|
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] StartTemperatureDataReceiving() - 温度数据接收已经在进行中,避免重复启动");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log("开始使用TCP方式接收温度数据");
|
Log("开始使用TCP方式接收温度数据");
|
||||||
@@ -896,25 +903,37 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
// 确保之前的连接已关闭
|
// 确保之前的连接已关闭
|
||||||
StopTemperatureDataReceiving();
|
StopTemperatureDataReceiving();
|
||||||
|
|
||||||
// 重置停止事件
|
// 在锁内执行所有关键状态更新,确保原子性
|
||||||
_stopTemperatureEvent = new ManualResetEvent(false);
|
|
||||||
lock (_lockObject)
|
lock (_lockObject)
|
||||||
{
|
{
|
||||||
|
// 重置停止事件
|
||||||
|
_stopTemperatureEvent?.Dispose();
|
||||||
|
_stopTemperatureEvent = new ManualResetEvent(false);
|
||||||
_isReceivingTemperatureData = true;
|
_isReceivingTemperatureData = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建并启动温度数据接收线程
|
// 创建并启动温度数据接收线程
|
||||||
_temperatureReceiveThread = new Thread(ReceiveTemperatureDataWithTcp)
|
Thread newThread = new Thread(ReceiveTemperatureDataWithTcp)
|
||||||
{
|
{
|
||||||
IsBackground = true,
|
IsBackground = true,
|
||||||
Name = "TemperatureReceiveThread"
|
Name = "TemperatureReceiveThread"
|
||||||
};
|
};
|
||||||
_temperatureReceiveThread.Start();
|
|
||||||
|
// 在锁内更新线程引用
|
||||||
|
lock (_lockObject)
|
||||||
|
{
|
||||||
|
_temperatureReceiveThread = newThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动线程
|
||||||
|
newThread.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;
|
||||||
@@ -943,26 +962,36 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 使用变量保存需要释放的资源,减少锁的持有时间
|
||||||
|
ManualResetEvent stopEventToDispose = null;
|
||||||
|
Thread threadToJoin = null;
|
||||||
|
NetworkStream streamToClose = null;
|
||||||
|
TcpClient clientToClose = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 线程安全地更新状态
|
// 在一个锁内收集所有需要清理的资源和更新状态
|
||||||
lock (_lockObject)
|
lock (_lockObject)
|
||||||
{
|
{
|
||||||
_isReceivingTemperatureData = false;
|
_isReceivingTemperatureData = false;
|
||||||
|
stopEventToDispose = _stopTemperatureEvent;
|
||||||
|
threadToJoin = _temperatureReceiveThread;
|
||||||
|
streamToClose = _temperatureStream;
|
||||||
|
clientToClose = _temperatureTcpClient;
|
||||||
|
|
||||||
|
// 立即重置引用,避免资源被重新使用
|
||||||
|
_temperatureStream = null;
|
||||||
|
_temperatureTcpClient = null;
|
||||||
|
_temperatureReceiveThread = null;
|
||||||
|
_stopTemperatureEvent = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 通知线程停止
|
// 在锁外通知线程停止,避免死锁
|
||||||
ManualResetEvent stopEvent = null;
|
if (stopEventToDispose != null)
|
||||||
lock (_lockObject)
|
|
||||||
{
|
|
||||||
stopEvent = _stopTemperatureEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stopEvent != null)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
stopEvent.Set();
|
stopEventToDispose.Set();
|
||||||
}
|
}
|
||||||
catch (ObjectDisposedException)
|
catch (ObjectDisposedException)
|
||||||
{
|
{
|
||||||
@@ -970,54 +999,75 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 等待线程结束
|
// 在锁外等待线程结束,避免死锁
|
||||||
Thread temperatureThread = null;
|
if (threadToJoin != null && threadToJoin.IsAlive)
|
||||||
lock (_lockObject)
|
|
||||||
{
|
{
|
||||||
temperatureThread = _temperatureReceiveThread;
|
Log("等待温度接收线程结束...");
|
||||||
|
// 增加等待时间,确保线程有足够时间完成清理
|
||||||
|
if (threadToJoin.Join(2000)) // 等待最多2秒
|
||||||
|
{
|
||||||
|
Log("温度接收线程已正常停止");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log("警告:温度接收线程可能未正常停止,已超时");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temperatureThread != null && temperatureThread.IsAlive)
|
// 在锁外关闭TCP客户端和流,避免死锁
|
||||||
{
|
if (streamToClose != null)
|
||||||
temperatureThread.Join(1000); // 等待最多1秒
|
|
||||||
Log("温度接收线程已停止");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭TCP客户端和流
|
|
||||||
NetworkStream stream = null;
|
|
||||||
TcpClient client = null;
|
|
||||||
|
|
||||||
lock (_lockObject)
|
|
||||||
{
|
|
||||||
stream = _temperatureStream;
|
|
||||||
client = _temperatureTcpClient;
|
|
||||||
_temperatureStream = null;
|
|
||||||
_temperatureTcpClient = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stream != null)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
stream.Close();
|
streamToClose.Close();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log($"关闭NetworkStream时出现异常: {ex.Message}");
|
||||||
}
|
}
|
||||||
catch (Exception)
|
|
||||||
{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client != null)
|
if (clientToClose != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
client.Close();
|
clientToClose.Close();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log($"关闭TcpClient时出现异常: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 释放停止事件
|
||||||
|
if (stopEventToDispose != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
stopEventToDispose.Dispose();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log($"释放ManualResetEvent时出现异常: {ex.Message}");
|
||||||
}
|
}
|
||||||
catch (Exception)
|
|
||||||
{}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] StopTemperatureDataReceiving() - 异常: {ex.Message}");
|
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] StopTemperatureDataReceiving() - 异常: {ex.Message}");
|
||||||
|
|
||||||
|
// 在异常情况下,再次尝试重置状态
|
||||||
|
try
|
||||||
|
{
|
||||||
|
lock (_lockObject)
|
||||||
|
{
|
||||||
|
_isReceivingTemperatureData = false;
|
||||||
|
_temperatureStream = null;
|
||||||
|
_temperatureTcpClient = null;
|
||||||
|
_temperatureReceiveThread = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -1032,63 +1082,131 @@ 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;
|
||||||
|
NetworkStream localStream = null;
|
||||||
|
List<byte> temperatureDataAccumulator = new List<byte>();
|
||||||
|
byte[] buffer = new byte[8192]; // 温度数据缓冲区
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 创建TCP客户端并连接到设备的温度数据端口
|
// 创建TCP客户端并连接到设备的温度数据端口
|
||||||
_temperatureTcpClient = new TcpClient
|
localTcpClient = new TcpClient
|
||||||
{
|
{
|
||||||
ReceiveTimeout = 5000,
|
ReceiveTimeout = 5000,
|
||||||
SendTimeout = 5000
|
SendTimeout = 5000
|
||||||
};
|
};
|
||||||
|
|
||||||
IAsyncResult result = _temperatureTcpClient.BeginConnect(_deviceIp, TEMPERATURE_TCP_PORT, null, null);
|
Log($"正在连接到温度数据端口 {TEMPERATURE_TCP_PORT}...");
|
||||||
|
IAsyncResult result = localTcpClient.BeginConnect(_deviceIp, TEMPERATURE_TCP_PORT, null, null);
|
||||||
bool connected = result.AsyncWaitHandle.WaitOne(3000, true);
|
bool connected = result.AsyncWaitHandle.WaitOne(3000, true);
|
||||||
|
|
||||||
if (!connected || !_temperatureTcpClient.Connected)
|
if (!connected || !localTcpClient.Connected)
|
||||||
{
|
{
|
||||||
Log("温度数据TCP连接失败,超时");
|
Log("温度数据TCP连接失败,超时");
|
||||||
|
localTcpClient.Close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_temperatureTcpClient.EndConnect(result);
|
localTcpClient.EndConnect(result);
|
||||||
Log("温度数据TCP连接成功");
|
Log("温度数据TCP连接成功");
|
||||||
|
|
||||||
// 获取网络流
|
// 获取网络流
|
||||||
_temperatureStream = _temperatureTcpClient.GetStream();
|
localStream = localTcpClient.GetStream();
|
||||||
_temperatureStream.ReadTimeout = 5000;
|
localStream.ReadTimeout = 5000;
|
||||||
|
|
||||||
byte[] buffer = new byte[8192]; // 温度数据缓冲区
|
// 更新类成员变量,在锁内进行
|
||||||
List<byte> temperatureDataAccumulator = new List<byte>();
|
lock (_lockObject)
|
||||||
|
{
|
||||||
|
_temperatureTcpClient = localTcpClient;
|
||||||
|
_temperatureStream = localStream;
|
||||||
|
}
|
||||||
|
|
||||||
// 发送开始温度数据传输的命令
|
// 发送开始温度数据传输的命令
|
||||||
byte[] startCommand = Encoding.ASCII.GetBytes("start_temp_transfer\r\n");
|
byte[] startCommand = Encoding.ASCII.GetBytes("start_temp_transfer\r\n");
|
||||||
_temperatureStream.Write(startCommand, 0, startCommand.Length);
|
localStream.Write(startCommand, 0, startCommand.Length);
|
||||||
_temperatureStream.Flush();
|
localStream.Flush();
|
||||||
|
|
||||||
Log("已发送开始温度数据传输命令,开始接收温度数据");
|
Log("已发送开始温度数据传输命令,开始接收温度数据");
|
||||||
|
|
||||||
while (!_stopTemperatureEvent.WaitOne(0))
|
// 使用局部变量引用停止事件,避免在循环中重复加锁
|
||||||
|
ManualResetEvent currentStopEvent = null;
|
||||||
|
lock (_lockObject)
|
||||||
{
|
{
|
||||||
|
currentStopEvent = _stopTemperatureEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 循环读取数据,使用更安全的退出机制
|
||||||
|
bool shouldContinue = true;
|
||||||
|
while (shouldContinue)
|
||||||
|
{
|
||||||
|
// 检查停止信号
|
||||||
|
if (currentStopEvent != null && currentStopEvent.WaitOne(0))
|
||||||
|
{
|
||||||
|
Log("接收到停止信号,准备退出温度数据接收循环");
|
||||||
|
shouldContinue = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否仍在接收状态
|
||||||
|
lock (_lockObject)
|
||||||
|
{
|
||||||
|
if (!_isReceivingTemperatureData)
|
||||||
|
{
|
||||||
|
Log("接收状态已更改,准备退出温度数据接收循环");
|
||||||
|
shouldContinue = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 检查连接状态
|
// 检查连接状态
|
||||||
if (!_temperatureTcpClient.Connected)
|
if (localTcpClient == null || !localTcpClient.Connected)
|
||||||
{
|
{
|
||||||
Log("温度数据TCP连接已断开");
|
Log("温度数据TCP连接已断开");
|
||||||
|
shouldContinue = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读取数据
|
// 检查流是否可读
|
||||||
int bytesRead = _temperatureStream.Read(buffer, 0, buffer.Length);
|
if (localStream == null || !localStream.CanRead)
|
||||||
if (bytesRead > 0)
|
|
||||||
{
|
{
|
||||||
// 将读取的数据添加到累积器
|
Log("网络流不可读,停止接收");
|
||||||
byte[] receivedBytes = new byte[bytesRead];
|
shouldContinue = false;
|
||||||
Array.Copy(buffer, receivedBytes, bytesRead);
|
break;
|
||||||
temperatureDataAccumulator.AddRange(receivedBytes);
|
}
|
||||||
|
|
||||||
// 处理累积的数据
|
// 检查是否有数据可读,避免阻塞
|
||||||
ProcessReceivedTemperatureData(temperatureDataAccumulator);
|
if (localStream.DataAvailable)
|
||||||
|
{
|
||||||
|
// 读取数据
|
||||||
|
int bytesRead = localStream.Read(buffer, 0, buffer.Length);
|
||||||
|
if (bytesRead > 0)
|
||||||
|
{
|
||||||
|
// 将读取的数据添加到累积器
|
||||||
|
byte[] receivedBytes = new byte[bytesRead];
|
||||||
|
Array.Copy(buffer, receivedBytes, bytesRead);
|
||||||
|
|
||||||
|
// 线程安全地更新累积器或直接处理
|
||||||
|
lock (temperatureDataAccumulator)
|
||||||
|
{
|
||||||
|
temperatureDataAccumulator.AddRange(receivedBytes);
|
||||||
|
ProcessReceivedTemperatureData(temperatureDataAccumulator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 读取到0字节表示连接已关闭
|
||||||
|
Log("远程主机关闭了连接");
|
||||||
|
shouldContinue = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 如果没有数据可读,短暂休眠避免CPU占用过高
|
||||||
|
Thread.Sleep(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (TimeoutException)
|
catch (TimeoutException)
|
||||||
@@ -1099,12 +1217,14 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
catch (IOException ex)
|
catch (IOException ex)
|
||||||
{
|
{
|
||||||
Log($"温度数据接收IO异常: {ex.Message}");
|
Log($"温度数据接收IO异常: {ex.Message}");
|
||||||
|
shouldContinue = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log($"温度数据接收异常: {ex.Message}");
|
Log($"温度数据接收异常: {ex.Message}");
|
||||||
// 非致命异常,继续尝试
|
// 非致命异常,短暂休眠后继续尝试
|
||||||
|
Thread.Sleep(100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1120,10 +1240,28 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
lock (_lockObject)
|
lock (_lockObject)
|
||||||
{
|
{
|
||||||
_isReceivingTemperatureData = false;
|
_isReceivingTemperatureData = false;
|
||||||
|
// 不在这里调用StopTemperatureDataReceiving,避免递归调用和潜在死锁
|
||||||
|
// 由调用者负责调用StopTemperatureDataReceiving
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清理资源
|
// 清理局部资源
|
||||||
StopTemperatureDataReceiving();
|
try
|
||||||
|
{
|
||||||
|
if (localStream != null)
|
||||||
|
{
|
||||||
|
localStream.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (localTcpClient != null)
|
||||||
|
{
|
||||||
|
localTcpClient.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,12 @@
|
|||||||
1. 暂停或恢复时,设置暂停状态,调用更新Info
|
1. 暂停或恢复时,设置暂停状态,调用更新Info
|
||||||
2. 断开或连接时,设置连接状态,调用更新Info
|
2. 断开或连接时,设置连接状态,调用更新Info
|
||||||
3. Ping通状态变化时,修改Ping状态,调用更新Info
|
3. Ping通状态变化时,修改Ping状态,调用更新Info
|
||||||
4. 图像更新时, 保存LastImage, 调用更新到UI
|
4. 温度数据更新时,调用更新Info
|
||||||
|
5. 图像更新时, 保存LastImage, 调用更新到UI
|
||||||
### 更新Info:
|
### 更新Info:
|
||||||
1. 如果暂停,显示暂停信息,否则如果Ping不通或断开,显示重连信息,否则清空InfoImage
|
1. 如果暂停,显示暂停信息,否则如果Ping不通或断开,显示重连信息,
|
||||||
2. 最后调用更新UI
|
2. 如果有温度数据,显示最高温度,否则清空Info
|
||||||
|
3. 最后调用更新UI
|
||||||
### 更新UI:
|
### 更新UI:
|
||||||
1. 先将LastImage绘制到全局缓冲
|
1. 先将LastImage绘制到全局缓冲
|
||||||
2. 再将InfoImage绘制到缓冲
|
2. 再将InfoImage绘制到缓冲
|
||||||
|
|||||||
Reference in New Issue
Block a user