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),失败设备可立即标记离线并继续 ,既保证启动速度,也让后续轮询线程快速进入"只与在线设备通信"的状态,实时性与用户体验同时提升

相关推荐
Eiceblue1 小时前
通过 C# 解析 HTML:文本提取 + 结构化数据获取
c#·html·.net·visual studio
一叶星殇1 小时前
.NET 6 NLog 实现多日志文件按业务模块拆分的实践
开发语言·.net
SunnyDays10111 小时前
使用 C# 将 Excel XLSX 或 XLS 转换为 HTML:完整指南
c#·excel转html·xlsx转html·xls转html
时光追逐者1 小时前
一款基于 .NET Avalonia 开源免费、快速、跨平台的图片查看器
c#·.net·图片查看器
酩酊仙人2 小时前
.Net机器学习入门
人工智能·机器学习·.net
CodeCraft Studio5 小时前
如何借助TeeChart图表库,实现放射治疗QA数据的精准可视化
信息可视化·.net·数据可视化·teechart·医疗软件·医疗数据分析·医用图表
老骥伏枥~14 小时前
VB.NET 中的单例模式
单例模式·.net
阿蒙Amon16 小时前
C#每日面试题-Thread.Sleep和Task.Delay的区别
java·数据库·c#
cfqq198916 小时前
Settings,变量保存
开发语言·c#
云草桑17 小时前
.net AI开发04 第八章 引入RAG知识库与文档管理核心能力及事件总线
数据库·人工智能·microsoft·c#·asp.net·.net·rag