**工控系统对资源管理、状态一致性和稳定性要求极高,单例模式在这里能解决很多核心问题。
一、先理解核心概念**
单例模式:保证一个类在整个应用程序生命周期中只有一个实例,并提供一个全局访问点。工控场景特点:需要和硬件(PLC、传感器、串口设备)通信、管理唯一的硬件连接、维护全局设备状态、避免资源冲突。
二、工控场景下单例模式的典型应用
1. 硬件通信管理(最核心应用)
工控系统中,一个硬件设备(如 PLC、串口仪表、扫码枪)通常只能有一个通信连接,多线程 / 多模块重复创建连接会导致通信异常、数据错乱甚至硬件锁死。
示例:PLC 通信单例类
using System;
using System.Threading;
// 模拟西门子PLC通信的单例类(线程安全版)
public sealed class PlcCommunication
{
// 1. 私有静态实例(懒加载+线程安全)
private static readonly Lazy<PlcCommunication> _instance = new Lazy<PlcCommunication>(() => new PlcCommunication(), LazyThreadSafetyMode.ExecutionAndPublication);
// 2. 模拟PLC连接状态
public bool IsConnected {
get; private set; }
// 3. 私有构造函数(禁止外部new)
private PlcCommunication()
{
// 构造时初始化连接(模拟)
ConnectToPlc();
}
// 4. 全局访问点
public static PlcCommunication Instance => _instance.Value;
// 模拟PLC连接方法
public void ConnectToPlc()
{
if (!IsConnected)
{
// 实际工控中:调用PLC SDK(如S7.Net、OPC UA客户端)建立连接
Console.WriteLine("PLC连接成功");
IsConnected = true;
}
}
// 模拟读取PLC寄存器数据
public int ReadPlcRegister(string registerAddress)
{
if (!IsConnected)
{
throw new InvalidOperationException("PLC未连接,无法读取数据");
}
// 实际工控中:调用SDK读取指定地址的数据
Console.WriteLine($"读取PLC寄存器 {
registerAddress} 数据");
return new Random().Next(0, 1000); // 模拟返回数据
}
// 模拟写入PLC寄存器数据
public void WritePlcRegister(string registerAddress, int value)
{
if (!IsConnected)
{
throw new InvalidOperationException("PLC未连接,无法写入数据");
}
// 实际工控中:调用SDK写入数据到指定地址
Console.WriteLine($"向PLC寄存器 {
registerAddress} 写入数据:{
value}");
}
// 断开PLC连接
public void DisconnectPlc()
{
if (IsConnected)
{
Console.WriteLine("PLC连接已断开");
IsConnected = false;
}
}
}
// 调用示例
public class IndustrialControlSystem
{
public static void Main()
{
// 无论在哪个模块调用,都是同一个PLC连接实例
var plc1 = PlcCommunication.Instance;
plc1.ReadPlcRegister("DB1.DBW0"); // 读取数据
var plc2 = PlcCommunication.Instance;
plc2.WritePlcRegister("DB1.DBW2", 500); // 写入数据

最低0.47元/天 解锁文章
2万+

被折叠的 条评论
为什么被折叠?



