需求是这样。开发一个类库,该类库核心功能是能够读取、写入、订阅PLC的数据,当用户订阅了某写数据时,如果这些数据发生变化,可以通过事件形式,将变化后的数据发给谁用户。
现在做了一个版本。大概思路如下:
1.定义一个接口(比如叫IDevice),该接口包含,链接,断开,读取,写入,订阅plc数据,以及当订阅的数据发生变化后执行的DataChanged事件。
2.实现IDevice接口,比如叫ModbusTcpDevice,该类实现了IDevice。并且ModbusTcpDevice中,缓存用户订阅的数据地址和值,再开一个后台线程,一直去读取 用户订阅的数据,把读取到的数据和缓存的数据比较,同一个地址,缓存数据和当前读取的数据不一致,就把新数据记录一下(比如叫 changedValues ),然后再把缓存值更新成当前值。 最后 执行 DataChanged 事件,传入刚才记录的变化值 (changedValues )。
由此联想的问题:
当一个程序链接较少的PLC 时,应该没什么问题。 如果要链接上百个甚至更多PLC时,每一个IDevice对象都有一个后台线程去轮询,会不会导致线程池爆炸呢?或者引发其他问题。
换成Task就可以 ,20万Task,只要不涉及到IO,没问题。
感谢您的回复。会涉及到I/O,从PLC 读取数据会有网络的I/O
@愤怒的小辣椒: 网络 IO没问题的,只要不涉及到磁盘IO就没问题的,我公司的IOT系统12万的设备都没问题的,Task是几万的
@需要格局: 我现在就是task的。相当于一个设备一个后台的tasi在一直循环读数据,然后发现订阅的数据变了,就触发datachange时间。如果同时几百或者更多设备,也就意味着几百或者更多task ,没问题吗?
@愤怒的小辣椒: 没问题的。只要Task中没有 磁盘IO,没问题。
几百个也不是问题呀. 可以考虑改成 一个主管理(timer)线程, 定时批量触发PLC读取.
IDeviceManager
_devices
--> add_device(IDevice device)
--> read_callback(fuction (device, data)[] frame)
--> _trigger_read() --> for _devices
--> read_callback
大致表达意思.
那如果其中一个 device 掉线 或者网络延迟很长,其他的是不是有受到影响了呢 ?