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