我通常以两种方式完成此操作:
1) 应用程序具有由单个线程拥有的单个 OPC 客户端实例。在读取/写入 OPC 值时,由客户端应用程序自动化的所有并行进程随后使用某种消息传递或与拥有 OPC 客户端的线程同步。
2) 每个线程拥有自己的私有 OPC 客户端,每个客户端都与 OPC 服务器独立通信。
就个人而言,我发现最常用的方案是前者。一个 OPC(或其他专有)客户端对象,带有对客户端进行同步调用的线程。确实,在几乎所有流程控制情况下,您都在使用多线程,目的是优雅地封装逻辑现实世界任务并将其与 UI 隔离,而不是为了任何类型的性能。这些线程可以承受等待数据的相对“较长”时间的阻塞——如果需要,PLC 会很高兴地按住堡垒一百毫秒。
您选择哪一种很大程度上取决于您的应用程序的规模和性质。对于花费很长时间等待外部实时事件的大量轻量级线程,在应用程序中保留单个 OPC 客户端实例并节省大量独立连接的开销是有意义的。对于少量繁重、快速移动、OPC 密集型线程,为每个线程提供自己的 OPC 客户端可能是有意义的。
还要记住你的 OPC 标签的刷新率——很多时候服务器只更新它们大约每 100 毫秒左右。即使是执行一次扫描,您的 PLC 也可能至少需要 10 毫秒。当数据永远不会那么快刷新时,让大量线程每秒独立轮询服务器一百次是没有意义的。
对于过程控制软件,您真正想要的是拥有大量空闲或低负载 CPU 时间——线程越轻越好。总体系统响应能力是关键,并且能够让您的软件处理高负载情况(在操作系统决定是时候索引 HDD 时,大量任务突然汇聚……可以说,净空保持齿轮润滑)。您的大多数线程可能大部分时间都在等待。事件和回调通常在这里最有意义。
此外,考虑 PLC 编程在这里也很重要。例如,在我的机器中,我有一些对时间非常关键的操作,同时,它们每次运行时都是唯一计时的——这些进程的持续时间大约为几分钟,计时到十分之一以下。一秒钟或更长时间,每天重复数百到数千次,并且每次运行时都具有关键但不同的持续时间。我已经看到这些处理方式有两种——一种在软件中,一种在 PLC 中。对于前一种情况,软件告诉 PLC 何时启动,然后一直运行,直到软件告诉它停止。这有明显的缺陷;在这种情况下,最好将时间间隔简单地发送到 PLC 并让它进行计时。