优化Tcp温度数据接收相关代码,使用局部变量减少全局变量依赖
This commit is contained in:
@@ -867,6 +867,10 @@ 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() - 开始执行");
|
||||||
|
|
||||||
|
// 局部变量用于跟踪线程状态
|
||||||
|
Thread newThread = null;
|
||||||
|
bool canProceed = false;
|
||||||
|
|
||||||
// 在设计模式下,跳过实际的温度数据接收
|
// 在设计模式下,跳过实际的温度数据接收
|
||||||
if (IsDesignMode)
|
if (IsDesignMode)
|
||||||
{
|
{
|
||||||
@@ -902,38 +906,44 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
_stopTemperatureEvent = new ManualResetEvent(false);
|
_stopTemperatureEvent = new ManualResetEvent(false);
|
||||||
// 设置接收状态为false,符合要求:系统初始化时,设置接收状态为false
|
// 设置接收状态为false,符合要求:系统初始化时,设置接收状态为false
|
||||||
_isReceivingTemperatureData = false;
|
_isReceivingTemperatureData = false;
|
||||||
|
_isTemperatureReceivingPaused = false; // 确保暂停状态也重置
|
||||||
|
|
||||||
// 创建并启动温度数据接收线程
|
// 创建并启动温度数据接收线程
|
||||||
Thread newThread = new Thread(ReceiveTemperatureDataWithTcp)
|
newThread = new Thread(ReceiveTemperatureDataWithTcp)
|
||||||
{
|
{
|
||||||
IsBackground = true,
|
IsBackground = true,
|
||||||
Name = "TemperatureReceiveThread"
|
Name = "TemperatureReceiveThread"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 更新全局线程引用
|
||||||
_temperatureReceiveThread = newThread;
|
_temperatureReceiveThread = newThread;
|
||||||
|
canProceed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log("开始使用TCP方式接收温度数据");
|
// 仅在可以继续的情况下启动线程
|
||||||
try
|
if (canProceed && newThread != null)
|
||||||
{
|
{
|
||||||
// 启动线程
|
Log("开始使用TCP方式接收温度数据");
|
||||||
_temperatureReceiveThread.Start();
|
try
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] StartTemperatureDataReceiving() - 异常: {ex.Message}");
|
|
||||||
|
|
||||||
lock (_lockObject)
|
|
||||||
{
|
{
|
||||||
_isReceivingTemperatureData = false;
|
// 启动线程
|
||||||
_temperatureReceiveThread = null;
|
newThread.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, "启动温度数据接收失败"));
|
||||||
}
|
}
|
||||||
|
|
||||||
OnConnectionException(new ConnectionExceptionEventArgs(ex, "启动温度数据接收失败"));
|
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] StartTemperatureDataReceiving() - 执行完成");
|
||||||
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] StartTemperatureDataReceiving() - 执行完成");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1009,17 +1019,25 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
{
|
{
|
||||||
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] StopTemperatureDataReceiving() - 开始执行");
|
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] StopTemperatureDataReceiving() - 开始执行");
|
||||||
|
|
||||||
if (_isDisposed)
|
// 使用局部变量检查对象是否已释放
|
||||||
|
bool objectDisposed = false;
|
||||||
|
lock (_lockObject)
|
||||||
|
{
|
||||||
|
objectDisposed = _isDisposed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (objectDisposed)
|
||||||
{
|
{
|
||||||
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] StopTemperatureDataReceiving() - 对象已释放,跳过操作");
|
Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] StopTemperatureDataReceiving() - 对象已释放,跳过操作");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用变量保存需要释放的资源,减少锁的持有时间
|
// 使用局部变量保存需要释放的资源,减少锁的持有时间
|
||||||
ManualResetEvent stopEventToDispose = null;
|
ManualResetEvent stopEventToDispose = null;
|
||||||
Thread threadToJoin = null;
|
Thread threadToJoin = null;
|
||||||
NetworkStream streamToClose = null;
|
|
||||||
TcpClient clientToClose = null;
|
// 定义常量
|
||||||
|
const int THREAD_JOIN_TIMEOUT_MS = 2000;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -1030,14 +1048,11 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
_isTemperatureReceivingPaused = false; // 同时重置暂停状态
|
_isTemperatureReceivingPaused = false; // 同时重置暂停状态
|
||||||
stopEventToDispose = _stopTemperatureEvent;
|
stopEventToDispose = _stopTemperatureEvent;
|
||||||
threadToJoin = _temperatureReceiveThread;
|
threadToJoin = _temperatureReceiveThread;
|
||||||
streamToClose = _temperatureStream;
|
|
||||||
clientToClose = _temperatureTcpClient;
|
|
||||||
|
|
||||||
// 立即重置引用,避免资源被重新使用
|
// 立即重置引用,避免资源被重新使用
|
||||||
_temperatureStream = null;
|
|
||||||
_temperatureTcpClient = null;
|
|
||||||
_temperatureReceiveThread = null;
|
_temperatureReceiveThread = null;
|
||||||
_stopTemperatureEvent = null;
|
_stopTemperatureEvent = null;
|
||||||
|
// 注意:不再重置_temperatureStream和_temperatureTcpClient,因为它们已在接收线程中作为局部变量处理
|
||||||
}
|
}
|
||||||
|
|
||||||
// 在锁外通知线程停止,避免死锁
|
// 在锁外通知线程停止,避免死锁
|
||||||
@@ -1058,41 +1073,16 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
{
|
{
|
||||||
Log("等待温度接收线程结束...");
|
Log("等待温度接收线程结束...");
|
||||||
// 增加等待时间,确保线程有足够时间完成清理
|
// 增加等待时间,确保线程有足够时间完成清理
|
||||||
if (threadToJoin.Join(2000)) // 等待最多2秒
|
if (threadToJoin.Join(THREAD_JOIN_TIMEOUT_MS)) // 等待最多2秒
|
||||||
{
|
{
|
||||||
Log("温度接收线程已正常停止");
|
Log("温度接收线程已正常停止");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log("警告:温度接收线程可能未正常停止,已超时");
|
Log("警告:温度接收线程可能未正常停止,已超时");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 在锁外关闭TCP客户端和流,避免死锁
|
|
||||||
if (streamToClose != null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
streamToClose.Close();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log($"关闭NetworkStream时出现异常: {ex.Message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clientToClose != null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
clientToClose.Close();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log($"关闭TcpClient时出现异常: {ex.Message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 释放停止事件
|
// 释放停止事件
|
||||||
if (stopEventToDispose != null)
|
if (stopEventToDispose != null)
|
||||||
{
|
{
|
||||||
@@ -1116,8 +1106,6 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
lock (_lockObject)
|
lock (_lockObject)
|
||||||
{
|
{
|
||||||
_isReceivingTemperatureData = false;
|
_isReceivingTemperatureData = false;
|
||||||
_temperatureStream = null;
|
|
||||||
_temperatureTcpClient = null;
|
|
||||||
_temperatureReceiveThread = null;
|
_temperatureReceiveThread = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1136,40 +1124,49 @@ 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() - 开始执行");
|
||||||
|
|
||||||
// 使用局部变量存储资源
|
// 使用局部变量存储资源,减少对全局变量的依赖
|
||||||
TcpClient localTcpClient = null;
|
TcpClient localTcpClient = null;
|
||||||
NetworkStream localStream = null;
|
NetworkStream localStream = null;
|
||||||
List<byte> temperatureDataAccumulator = new List<byte>();
|
List<byte> temperatureDataAccumulator = new List<byte>();
|
||||||
byte[] buffer = new byte[65536]; // 缓冲区大小
|
byte[] buffer = new byte[65536]; // 缓冲区大小
|
||||||
|
|
||||||
|
// 定义常量,避免魔法数字
|
||||||
|
const int RECEIVE_TIMEOUT = 5000;
|
||||||
|
const int SHORT_SLEEP_MS = 10;
|
||||||
|
const int MEDIUM_SLEEP_MS = 50;
|
||||||
|
const int LONG_SLEEP_MS = 1000;
|
||||||
|
const int ERROR_SLEEP_MS = 100;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 主循环,持续执行直到收到停止信号
|
// 主循环,持续执行直到收到停止信号
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
// 检查停止信号
|
// 检查停止信号和对象是否已释放
|
||||||
bool stopRequested = false;
|
bool shouldStop = false;
|
||||||
lock (_lockObject)
|
lock (_lockObject)
|
||||||
{
|
{
|
||||||
if (_stopTemperatureEvent != null && _stopTemperatureEvent.WaitOne(0))
|
shouldStop = (_stopTemperatureEvent != null && _stopTemperatureEvent.WaitOne(0)) || _isDisposed;
|
||||||
{
|
|
||||||
stopRequested = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stopRequested)
|
if (shouldStop)
|
||||||
{
|
{
|
||||||
Log("接收到停止信号,准备退出温度数据接收循环");
|
Log("接收到停止信号或对象已释放,准备退出温度数据接收循环");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取当前接收状态和暂停状态
|
// 获取当前接收状态、暂停状态和设备IP
|
||||||
bool isReceiving = false;
|
bool isReceiving = false;
|
||||||
bool isPaused = false;
|
bool isPaused = false;
|
||||||
|
string deviceIp = null;
|
||||||
|
int temperaturePort = 0;
|
||||||
|
|
||||||
lock (_lockObject)
|
lock (_lockObject)
|
||||||
{
|
{
|
||||||
isReceiving = _isReceivingTemperatureData;
|
isReceiving = _isReceivingTemperatureData;
|
||||||
isPaused = _isTemperatureReceivingPaused;
|
isPaused = _isTemperatureReceivingPaused;
|
||||||
|
deviceIp = _deviceIp;
|
||||||
|
temperaturePort = TEMPERATURE_TCP_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据用户要求的逻辑处理
|
// 根据用户要求的逻辑处理
|
||||||
@@ -1180,7 +1177,7 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
{
|
{
|
||||||
// 如果暂停,则Sleep 1秒后继续
|
// 如果暂停,则Sleep 1秒后继续
|
||||||
Log("接收状态为false且处于暂停状态,等待1秒后继续");
|
Log("接收状态为false且处于暂停状态,等待1秒后继续");
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(LONG_SLEEP_MS);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1212,23 +1209,21 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
// 创建TCP客户端并连接
|
// 创建TCP客户端并连接
|
||||||
localTcpClient = new TcpClient
|
localTcpClient = new TcpClient
|
||||||
{
|
{
|
||||||
ReceiveTimeout = 5000,
|
ReceiveTimeout = RECEIVE_TIMEOUT,
|
||||||
SendTimeout = 5000
|
SendTimeout = RECEIVE_TIMEOUT
|
||||||
};
|
};
|
||||||
|
|
||||||
Log($"正在连接到温度数据端口 {TEMPERATURE_TCP_PORT}...");
|
Log($"正在连接到温度数据端口 {temperaturePort}...");
|
||||||
localTcpClient.Connect(_deviceIp, TEMPERATURE_TCP_PORT);
|
localTcpClient.Connect(deviceIp, temperaturePort);
|
||||||
Log("温度数据TCP连接成功");
|
Log("温度数据TCP连接成功");
|
||||||
|
|
||||||
// 获取网络流
|
// 获取网络流
|
||||||
localStream = localTcpClient.GetStream();
|
localStream = localTcpClient.GetStream();
|
||||||
localStream.ReadTimeout = 5000;
|
localStream.ReadTimeout = RECEIVE_TIMEOUT;
|
||||||
|
|
||||||
// 更新类成员变量和状态
|
// 只更新必要的状态标志
|
||||||
lock (_lockObject)
|
lock (_lockObject)
|
||||||
{
|
{
|
||||||
_temperatureTcpClient = localTcpClient;
|
|
||||||
_temperatureStream = localStream;
|
|
||||||
_isReceivingTemperatureData = true;
|
_isReceivingTemperatureData = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1238,14 +1233,14 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
localStream.Flush();
|
localStream.Flush();
|
||||||
Log("已发送开始温度数据传输命令");
|
Log("已发送开始温度数据传输命令");
|
||||||
|
|
||||||
// 更新状态标志
|
// 更新局部状态标志
|
||||||
isReceiving = true;
|
isReceiving = true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log($"TCP连接或初始化失败: {ex.Message}");
|
Log($"TCP连接或初始化失败: {ex.Message}");
|
||||||
// 连接失败后等待1秒再重试
|
// 连接失败后等待1秒再重试
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(LONG_SLEEP_MS);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1274,11 +1269,11 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 否则同步接收并处理数据
|
// 否则同步接收并处理数据
|
||||||
//lock (temperatureDataAccumulator)
|
lock (temperatureDataAccumulator)
|
||||||
//{
|
{
|
||||||
// temperatureDataAccumulator.AddRange(receivedBytes);
|
temperatureDataAccumulator.AddRange(receivedBytes);
|
||||||
// ProcessReceivedTemperatureData(temperatureDataAccumulator);
|
ProcessReceivedTemperatureData(temperatureDataAccumulator);
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1289,13 +1284,22 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
{
|
{
|
||||||
_isReceivingTemperatureData = false;
|
_isReceivingTemperatureData = false;
|
||||||
}
|
}
|
||||||
|
// 清理连接资源
|
||||||
|
try
|
||||||
|
{
|
||||||
|
localStream.Close();
|
||||||
|
localTcpClient.Close();
|
||||||
|
}
|
||||||
|
catch {}
|
||||||
|
localStream = null;
|
||||||
|
localTcpClient = null;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 短暂休眠避免CPU占用过高
|
// 短暂休眠避免CPU占用过高
|
||||||
Thread.Sleep(10);
|
Thread.Sleep(SHORT_SLEEP_MS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -1306,14 +1310,23 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
{
|
{
|
||||||
_isReceivingTemperatureData = false;
|
_isReceivingTemperatureData = false;
|
||||||
}
|
}
|
||||||
|
// 清理连接资源
|
||||||
|
try
|
||||||
|
{
|
||||||
|
localStream.Close();
|
||||||
|
localTcpClient.Close();
|
||||||
|
}
|
||||||
|
catch {}
|
||||||
|
localStream = null;
|
||||||
|
localTcpClient = null;
|
||||||
// 短暂休眠后重试
|
// 短暂休眠后重试
|
||||||
Thread.Sleep(100);
|
Thread.Sleep(ERROR_SLEEP_MS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 没有有效连接,短暂休眠
|
// 没有有效连接,短暂休眠
|
||||||
Thread.Sleep(50);
|
Thread.Sleep(MEDIUM_SLEEP_MS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1329,8 +1342,6 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
lock (_lockObject)
|
lock (_lockObject)
|
||||||
{
|
{
|
||||||
_isReceivingTemperatureData = false;
|
_isReceivingTemperatureData = false;
|
||||||
_temperatureStream = null;
|
|
||||||
_temperatureTcpClient = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清理资源
|
// 清理资源
|
||||||
@@ -1339,6 +1350,7 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
if (localStream != null)
|
if (localStream != null)
|
||||||
{
|
{
|
||||||
localStream.Close();
|
localStream.Close();
|
||||||
|
localStream = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch {}
|
catch {}
|
||||||
@@ -1348,6 +1360,7 @@ namespace JoyD.Windows.CS.Toprie
|
|||||||
if (localTcpClient != null)
|
if (localTcpClient != null)
|
||||||
{
|
{
|
||||||
localTcpClient.Close();
|
localTcpClient.Close();
|
||||||
|
localTcpClient = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch {}
|
catch {}
|
||||||
|
|||||||
Reference in New Issue
Block a user