From 5ffc61b9037d23e8fba7859bdae47b4030b767c3 Mon Sep 17 00:00:00 2001 From: "GukSang.Jin" Date: Wed, 7 Jan 2026 18:11:06 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WindowsFormsApp6/MainForm.cs | 70 ++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/WindowsFormsApp6/MainForm.cs b/WindowsFormsApp6/MainForm.cs index e48d8bc..ae09f69 100644 --- a/WindowsFormsApp6/MainForm.cs +++ b/WindowsFormsApp6/MainForm.cs @@ -26,6 +26,11 @@ namespace WindowsFormsApp6 private SerialPort _serialPort; private IModbusMaster _modbusMaster; private System.Windows.Forms.Timer _readTimer; + + // 超时计数器 + private int _timeoutCount = 0; + private const int MAX_TIMEOUT_COUNT = 5; // 连续超时5次后提示 + private bool _isClosing = false; // 标记是否正在关闭 // Form1历史数据缓存(用于累积显示) private List form1TimeValues = new List(); @@ -242,7 +247,7 @@ namespace WindowsFormsApp6 /// private void ReadTimer_Tick(object sender, EventArgs e) { - if (_modbusMaster == null || _serialPort == null || !_serialPort.IsOpen) + if (_isClosing || _modbusMaster == null || _serialPort == null || !_serialPort.IsOpen) return; try @@ -281,13 +286,59 @@ namespace WindowsFormsApp6 // 读取完成后清除信号量 WriteCoil(slaveId, 310, false); } + + // 通信成功,重置超时计数器 + _timeoutCount = 0; + } + catch (TimeoutException tex) + { + // 超时异常处理 + _timeoutCount++; + System.Diagnostics.Debug.WriteLine($"Modbus通信超时({_timeoutCount}/{MAX_TIMEOUT_COUNT}):{tex.Message}"); + + if (_timeoutCount >= MAX_TIMEOUT_COUNT) + { + HandleCommunicationTimeout(); + } } catch (Exception ex) { - // 读取失败时不弹窗,避免频繁打扰用户 - System.Diagnostics.Debug.WriteLine($"Modbus读取失败:{ex.Message}"); + // 其他异常也计入超时 + _timeoutCount++; + System.Diagnostics.Debug.WriteLine($"Modbus读取失败({_timeoutCount}/{MAX_TIMEOUT_COUNT}):{ex.Message}"); + + if (_timeoutCount >= MAX_TIMEOUT_COUNT) + { + HandleCommunicationTimeout(); + } } } + + /// + /// 处理通信超时 + /// + private void HandleCommunicationTimeout() + { + if (_isClosing) return; + + _isClosing = true; + + // 停止定时器 + _readTimer?.Stop(); + + // 在UI线程上显示提示并关闭 + this.Invoke(new Action(() => + { + MessageBox.Show( + $"Modbus通信连续超时{MAX_TIMEOUT_COUNT}次,设备可能已断开连接。\n程序将自动关闭。", + "通信超时", + MessageBoxButtons.OK, + MessageBoxIcon.Warning); + + // 关闭窗体 + this.Close(); + })); + } /// /// 读取单个线圈状态 @@ -299,6 +350,11 @@ namespace WindowsFormsApp6 bool[] coils = _modbusMaster.ReadCoils(slaveId, address, 1); return coils[0]; } + catch (TimeoutException) + { + // 超时异常向上抛出 + throw; + } catch { return false; @@ -314,6 +370,12 @@ namespace WindowsFormsApp6 { _modbusMaster.WriteSingleCoil(slaveId, address, value); } + catch (TimeoutException tex) + { + System.Diagnostics.Debug.WriteLine($"写入线圈超时:{tex.Message}"); + // 超时异常向上抛出 + throw; + } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"写入线圈失败:{ex.Message}"); @@ -2390,6 +2452,8 @@ namespace WindowsFormsApp6 private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { + _isClosing = true; + // 停止并释放定时器 timeUpdateTimer?.Stop(); timeUpdateTimer?.Dispose();