OPCUA的同步异步写入
一、同步写入
写入无返回值
Session.Write
OpcUAHelper只是对连接做了很大的简化,读写都差不多
writeValue.Value.Value 两层
DataValue类型的.Value
报错:类型不匹配 BadType.Mismatch

1、写入动作有没有成功?
StatusCode.IsGood(item)
没有成功返回False 才处理抛出异常
成功不处理
2、保持数据类型一致格式
Word数据类型,存储2个字节
双字4个字节
666默认是int类型,c#是四个字节
2个字节的word存入了4个字节的int类型
ushort value=666;
调用方法,逆推参数类型怎么填写
// 同步写入 private static void Write(Session session) { WriteValueCollection writeValues = new WriteValueCollection(); WriteValue writeValue = new WriteValue(); writeValue.NodeId = "ns=2;s=通道 1.设备 1.标记 2"; writeValue.AttributeId = Attributes.Value; ushort value = 666; writeValue.Value.Value = value; // 666 默认是int C# 4字节 类型不匹配 writeValues.Add(writeValue); //RequestHeader requestHeader, //WriteValueCollection nodesToWrite, //out StatusCodeCollection results, //out DiagnosticInfoCollection diagnosticInfos session.Write( null, writeValues, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos ); foreach (var item in results) { Console.WriteLine(StatusCode.IsGood(item)); } }
二、异步写入
1、BeginWrite WriteAsync两个方法


参数异步回调AsyncCallback callback是一个实例要new

new 实例化构造函数要接收一个IAsyncResult 参数,无返回值类型的方法
定义private static void WriteCompleted(IAsyncResult result)
把方法名放到new AsyncCallback(WriteCompleted)里面进行初始化
回调会调用这个方法WriteCompleted
最后一个参数 object asyncState
类似之前将socket对象的时候,这个参数会当成参数IAsyncResult result传入回调方法WriteCompleted
var session = result.AsyncState as Session;
回调方法确定是否写入成功,读取的结果更丰富一些,同步只返回 状态
OPCUA是基于socket对象的,很多动作都是借鉴socket
// 异步写入 BeginWrite WriteAsync private static void AsyncWrite(Session session) { WriteValueCollection writeValues = new WriteValueCollection(); WriteValue writeValue = new WriteValue(); writeValue.NodeId = "ns=2;s=通道 1.设备 1.标记 2"; writeValue.AttributeId = Attributes.Value; ushort value = 555; writeValue.Value.Value = value; // 666 默认是int C# 4字节 类型不匹配 writeValues.Add(writeValue); session.BeginWrite(null, writeValues, new AsyncCallback(WriteCompleted), session); } private static void WriteCompleted(IAsyncResult result) { var session = result.AsyncState as Session; session.EndWrite(result, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos); foreach (var item in results) { Console.WriteLine(StatusCode.IsGood(item)); } }
2、AsyncWrite写法,相对简单一些,一个方法Task方式处理
CancellationToken:异步的取消机制

拿到WriteResponse而不是Task,可以await等待拿到结果返回

返回结果

private static async void AsyncWrite(Session session, object obj) { WriteValueCollection writeValues = new WriteValueCollection(); WriteValue writeValue = new WriteValue(); writeValue.NodeId = "ns=2;s=通道 1.设备 1.标记 1"; writeValue.AttributeId = Attributes.Value; ushort value = 111; writeValue.Value.Value = value; // 666 默认是int C# 4字节 类型不匹配 writeValues.Add(writeValue); CancellationToken token = new CancellationToken(); WriteResponse response = await session.WriteAsync(null, writeValues, token); }
异步方式还是挺有必要的,OPC的效率并不是很高,通讯过程有追求的,还是采用异步
浙公网安备 33010602011771号