一、环境配置与基础依赖
开发环境要求
.NET Framework 4.6.1+ 或 .NET Core 3.1+
Visual Studio 2019+
OPC Foundation库(通过NuGet安装)
Install-Package OpcFoundation.OpcDa
关键依赖项
usingOpc.Da;// OPC DA核心接口usingOpc.Com;// COM互操作支持usingSystem;usingSystem.Collections.Generic;
二、核心功能实现
1. OPC服务器连接管理
publicclassOpcDaClient:IDisposable{privateServer_server;privateConnection_connection;privateGroup_group;publicboolConnect(stringserverUrl){try{_connection=newConnection();_connection.URL=serverUrl;_connection.Timeout=5000;// 5秒超时_server=newServer(_connection);_server.Connect();if(_server.ServerState==Opc.Da.ServerState.Connected){InitializeGroup();returntrue;}returnfalse;}catch(OpcCom.Da.ServerExceptionex){Console.WriteLine($"连接失败:{ex.Message}");returnfalse;}}privatevoidInitializeGroup(){_group=_server.AddGroup("ClientGroup");_group.IsActive=true;_group.UpdateRate=1000;// 1秒更新周期}publicvoidDisconnect(){_group?.Dispose();_server?.Disconnect();}}2. 数据项订阅与读取
publicclassOpcDaClient{// ... 上文代码publicvoidAddItems(IEnumerable<string>itemIds){varitems=newList<Item>();foreach(varidinitemIds){varitem=newItem(id);item.ClientHandle=Guid.NewGuid().GetHashCode();// 唯一客户端句柄item.Active=true;items.Add(item);}_group.AddItems(items.ToArray());SubscribeDataChanges();}privatevoidSubscribeDataChanges(){_group.DataChange+=(sender,e)=>{for(inti=1;i<e.NumItems;i++){varvalue=e.ItemValues.GetValue(i);varquality=e.Qualities.GetValue(i);vartimestamp=e.TimeStamps.GetValue(i);Console.WriteLine($"[{DateTime.Now}]{e.ItemIDs.GetValue(i)}:{value}({quality})");}};}publicobjectReadItem(stringitemId){varitem=_group.Items.Find(i=>i.ItemID==itemId);if(item!=null){returnitem.Value;}returnnull;}}三、完整使用示例
classProgram{staticvoidMain(string[]args){using(varclient=newOpcDaClient()){if(client.Connect("opc.da://localhost/Kepware.KEPServerEX.V6")){// 添加监控项client.AddItems(new[]{"Random.Real8","Machine.Status"});// 同步读取示例varvalue=client.ReadItem("Random.Real8");Console.WriteLine($"同步读取值:{value}");Console.WriteLine("按任意键退出...");Console.ReadKey();}}}}四、高级功能实现
1. 异步数据读取
publicasyncTask<object>ReadItemAsync(stringitemId){varitem=_group.Items.Find(i=>i.ItemID==itemId);if(item==null)returnnull;returnawaitTask.Run(()=>item.Value);}2. 批量写入操作
publicvoidWriteItems(Dictionary<string,object>values){varitems=newList<Item>();foreach(varkvpinvalues){varitem=_group.Items.Find(i=>i.ItemID==kvp.Key);if(item!=null){item.Value=kvp.Value;items.Add(item);}}_group.WriteItems(items.ToArray());}五、异常处理与最佳实践
连接异常处理
try{client.Connect("opc.da://invalid-server");}catch(OpcCom.Da.ServerNotFoundException){Console.WriteLine("服务器未找到");}catch(OpcCom.Da.UnauthorizedAccessException){Console.WriteLine("认证失败");}资源释放
publicvoidDispose(){_group?.Dispose();_server?.Dispose();_connection?.Dispose();}多线程安全
privatereadonlyobject_lock=newobject();publicvoidSafeWrite(stringitemId,objectvalue){lock(_lock){varitem=_group.Items.Find(i=>i.ItemID==itemId);item?.Value=value;}}
六、依赖项配置说明
NuGet包管理
<!--.csproj文件--><ItemGroup><PackageReferenceInclude="OpcFoundation.OpcDa"Version="3.0.0"/></ItemGroup>COM组件注册
若使用OPCDAAuto.dll:
regsvr32 OPCDAAuto.dll在代码中引用:
usingOPC.Automation;
参考代码 OPC DA(客户端)源码www.youwenfan.com/contentcsq/46008.html
七、调试与测试
日志记录
publicvoidLog(stringmessage){File.AppendAllText("opc_log.txt",$"{DateTime.Now}:{message}{Environment.NewLine}");}模拟服务器测试
使用Matrikon OPC Server Simulation进行单元测试:
[Test]publicvoidTestConnect(){varclient=newOpcDaClient();Assert.IsTrue(client.Connect("opc.da://localhost/Matrikon.Server.1"));}