3.NModbus4 长距离多设备超时 C# + WPF 完整示例

cs 复制代码
/// <summary>
/// 当前是否已建立 Modbus-TCP 连接(只读,由 Connect/Disconnect 维护)
/// </summary>
public bool IsConnected;

/// <summary>
/// 建立 Modbus-TCP 连接
/// 调用前请先设置 <see cref="IpAddress"/> 与 <see cref="ServerPort"/>
/// </summary>
/// <returns>true 成功;false 失败(异常已内部记录)</returns>
public bool Connect()
{
    // 100 ms 取消令牌 → 避免半开连接长时间阻塞 UI
    using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(0.1));

    try
    {
        // 1. 创建 TcpClient 并禁用 Nagle,降低小包延迟
        _tcpClient = new TcpClient
        {
            SendTimeout    = 100,   // 发送超时 100 ms
            ReceiveTimeout = 100,   // 接收超时 100 ms
            NoDelay        = true   // 立即发送,不等待合并
        };

        // 2. 异步连接,最多等待 5 秒(与令牌叠加)
        var connectTask = _tcpClient.ConnectAsync(IpAddress, ServerPort);
        connectTask.Wait(cts.Token);        // 先受 100 ms 令牌限制
        connectTask.GetAwaiter().GetResult(); // 再抛异常

        // 3. 连接成功 → 创建 NModbus 主站实例
        IsConnected   = _tcpClient.Connected;
        _modbusMaster = ModbusIpMaster.CreateIp(_tcpClient);

        return true;
    }
    catch (Exception ex)
    {
        // 记录失败状态与日志
        IsConnected = false;
        Debug.WriteLine($"Connection error: {ex.Message}");
        return false;
    }
}

如果你刚接触 Modbus-TCP,建议先回看《12.NModbus4在C#上的部署与使用 C#例子 WPF例子》等往期文章------那里已经演示了如何引用 NModbus4、创建 TcpClient、构建 ModbusIpMaster 并读取第一个寄存器。本文默认你已能完成"建连接 → 读寄存器"这一最小闭环,下面直接切入"连接阶段最容易被忽视、却又最影响实时性"的环节:超时。

示例代码把"建连"做成 Connect() 方法,内部用 ConnectAsync(IpAddress, ServerPort) 异步发起 TCP 三次握手,同时给 CancellationTokenSource 设定 100 ms 取消令牌;这意味着:

  • 网络瞬间可达时,连接在几十毫秒内完成,令牌不会触发,流程无感通过;

  • 一旦出现半开连接、IP 不可达或端口未监听,最多只阻塞 100 ms 就会被强制取消,避免 UI 卡死。

    此外,代码把 TcpClient.NoDelay = true 放在连接前,确保小包立即发出,减少第一个 Modbus 请求的延迟

当你要轮询 80 台设备时,如果每台都"等 1-2 秒才报连接失败",总启动时间 = 80 × 2 s = 160 s ,界面直接假死。把连接超时压到 100 ms 后,80 台总探测时间 < 8 s (并行甚至 < 0.2 s),失败设备可立即标记离线并继续 ,既保证启动速度,也让后续轮询线程快速进入"只与在线设备通信"的状态,实时性与用户体验同时提升

相关推荐
波波0071 小时前
C# 15 重磅新特性: 带标签 break 与 continue:重新定义嵌套循环控制流
服务器·前端·c#
wujian83115 小时前
怎么用千问生成word文档:从「格式崩」到「一键过」,AI导出鸭打通最后半厘米
人工智能·ai·c#·word·豆包·deepseek·ai导出鸭
zlinear数据采集卡6 小时前
D223上位机C#开发实战:从帧解析到波形显示的完整实现
开发语言·arm开发·嵌入式硬件·fpga开发·开源·c#
唐青枫7 小时前
别把 ImmutableArray 当成只读 List:C#.NET 不可变数组深入详解
c#·.net
zlinear数据采集卡10 小时前
D223 ADC数据处理流水线:从原始采样值到工程单位的完整转换链
开发语言·arm开发·嵌入式硬件·fpga开发·开源·c#
花落人散处13 小时前
CDiskClean 开发历程 —— 文件清理_目录树解析实现方案参考
c#
离陌在学C#14 小时前
C# 泛型:从基础到高级应用
开发语言·c#
Vertira14 小时前
C# 与 OpencvSharp 编程[基础目录]
c#
Polevne16 小时前
WPF\MAUI\Avalonia Dispatcher
wpf