为什么.net4.5+NModbus3.0.74连不上,换成3.0.83+.net4.8 连成功了 但是也不知改了什么代码,还是2个版本切换多次后工程坏掉了,.net4.8也连不上了,后面换成NModbus4就完全没问题了。但是读取多次数据后就崩溃了。刚才聊天多次改了这么多功能后不崩了
搜索 3 个关键词,参考 18 篇资料
完整复盘你整套踩坑全过程(版本 + 框架 + 代码三重坑,现在改完逻辑刚好根治)
一、NModbus3.0.74 (.NET4.5) 连不上、3.0.83 (.NET4.8) 能连上原因
二、换到 NModbus4 初期频繁读取崩溃的根源(你之前的致命代码缺陷)
崩溃核心 2 点:
NModbus3 老版本是短连接模型(每次读写新建 TCP),NModbus4 改成长连接复用,老代码直接沿用全局变量就炸。
三、你现在改完代码不再崩溃的本质优化(刚好命中 NModbus4 稳定用法)
1. SyncLock _lockObj锁重连逻辑
销毁 + 新建连接串行化,杜绝多线程同时 Dispose / 新建 Master 导致空引用、并发改全局对象。
vb
If _modbusMaster IsNot Nothing Then _modbusMaster.Dispose()
If _tcpClient IsNot Nothing Then _tcpClient.Close():_tcpClient.Dispose()
每次重连彻底销毁旧连接、释放 Socket 句柄,杜绝句柄泄漏。
2. ConnectPLC 每次内部New TcpClient,不再复用全局 TCP
重连 = 全新 Socket + 全新 Master,坏连接直接丢弃,从根源规避长连接假死、报文错乱问题(NModbus4 最优工业用法:故障即弃连接、重连新建实例)。
3. 分层异步 + 同步等待合理区分
- InitIP_Port:Await ConnectPLC(),初始化异步等连接完再开通信线程,不会线程提前跑空对象;
- ProcessRequests轮询:.Result同步阻塞等待重连 +Thread.Sleep(3000),故障轮询限流,疯狂重试榨干系统资源的问题消失。
四、最终总结
后续固化小优化(可选)
vb
Try
_modbusMaster?.Dispose()
Catch
End Try





