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的效率并不是很高,通讯过程有追求的,还是采用异步

 

posted on 2025-03-19 13:37  张彦山  阅读(198)  评论(0)    收藏  举报