Access Data via Symbol handles

The Read/Write Access by handle solves the issue of directly accessing the process image like the symbol path access. Because the address is accessed indirectly by the symbol path creating a variable handle, the read/write works also when the data object has changed its position within the process image.

However the cost for this are two extra ADS communication roundtrips by the 'CreateVariableHandle' and 'DeleteVariableHandle' calls compared to the IndexGroup/IndexOffset access methods. It is the responsibility of the application code to optimize these accesses.

Asynchronous access

Access symbolic values by handle

CancellationToken cancelT = CancellationToken.None;
using (AdsClient client = new AdsClient())
{
    client.Connect(AmsNetId.Local, 851);

    ushort valueToRead = 0; // System.UInt16
    ushort valueToWrite = 42; // System.UInt16

    // Create the Variable Handle
    ResultHandle resultHandle = await client.CreateVariableHandleAsync("MAIN.testVar", cancel); //Test Var is defined as PLC INT

    if (resultHandle.Succeeded)
    {
        uint varHandle = 0;

        try
        {
            // Write an UINT16 Value
            byte[] writeData = new byte[sizeof(ushort)];

            MemoryStream writeStream = new MemoryStream(writeData);
            BinaryWriter writer = new BinaryWriter(writeStream);
            writer.Write(valueToWrite); // Marshal the Value
            ResultWrite resultWrite = await client.WriteAsync(varHandle, writeData.AsMemory(), cancelT);

            bool succeeded = resultWrite.Succeeded;

            // Read an UINT16 Value
            byte[] readData = new byte[sizeof(ushort)];
            ResultRead resultRead = await client.ReadAsync(varHandle, readData.AsMemory(), cancel);

            if (resultRead.Succeeded)
            {
                MemoryStream readStream = new MemoryStream(readData);
                BinaryReader reader = new BinaryReader(readStream);
                valueToRead = reader.ReadUInt16(); // Unmarshal the Value
            }
        }
        finally
        {
            // Unregister VarHandle after Use
            ResultAds result = await client.DeleteVariableHandleAsync(varHandle, cancel);
        }
    }
}

Synchronous access

Access symbolic values by handle

using (AdsClient client = new AdsClient())
{
    uint varHandle = 0;
    client.Connect(AmsNetId.Local, 851);
    try
    {
        UInt16 valueToRead = 0;
        UInt16 valueToWrite = 42;

        // Create the Variable Handle
        varHandle = client.CreateVariableHandle("MAIN.testVar"); //Test Var is defined as PLC INT

        // Write an UINT16 Value
        byte[] writeData = new byte[sizeof(ushort)];

        MemoryStream writeStream = new MemoryStream(writeData);
        BinaryWriter writer = new BinaryWriter(writeStream);
        writer.Write(valueToWrite); // Marshal the Value
        client.Write(varHandle, writeData.AsMemory());

        // Read an UINT16 Value
        byte[] readData = new byte[sizeof(ushort)];

        MemoryStream readStream = new MemoryStream(readData);
        client.Read(varHandle, readData.AsMemory());
        BinaryReader reader = new BinaryReader(readStream);
        valueToRead = reader.ReadUInt16(); // Unmarshal the Value
    }
    finally
    {
        // Unregister VarHandle after Use
        client.DeleteVariableHandle(varHandle);
    }
}