Upgrading existing ADS Application code (Version 4.X --> 5.X)

Code migration path for application code Beckhoff.TwinCAT.Ads 4.X --> 5.X

The Beckhoff.TwinCAT.Ads package Version 4.X implements the Beckhoff ADS API for the Microsoft .NET FullFramework (>= 4.0) / CompactFramework (>= 2.0). Newer .NET framework implementations are basing on '.NET Core' (e.g. .NET 5.0).

To support these newer flavours like .NET Core, .NET Standard together with its new features, a new Version 5.X of the Beckhoff.TwinCAT.Ads API is available.

Because new platform features need some breaking changes within the API for seamless support, the decision was taken to remove some legacy features and burdens in the reimplementation. Nevertheless most of the interfaces remained stable and only a few approaches changed.

The breaking changes and some guidlines will be discussed here.

Use 'async' wherever possible.

Internally, the Beckhoff.TwinCAT.Ads package are implemented asynchronously (Methodnames ending with 'Async'). The synchronous counterparts of the async methods are implemented as thin wrapper around the async method with synchronization.

As consequence the synchronous method is less flexible (only usable in synchronous code paths) and less performant (blocking calls, more thread switches). Furthermore, with the 'async' keyword support of .NET they are also not easier to use. So take more than a thought about migrate to async code.

Synchronous Read value

uint variableHandle = ...;
int value;
AdsErrorCode errorCode = adsClient.TryReadValue<int>(variableHandle, out int value);

Asynchronous

uint variableHandle = ...;
ResultValue<int> result = await adsClient.ReadValueAsync(variableHandle, CancellationToken.None);
AdsErrorCode errorCode = result.ErrorCode;
int value = result.Value;

However in synchronous application code paths the await keyword is not allowed. Using the synchronous methods is the only option besides migrating the whole application code up to the main root. Further information can be found here: Asynchronous programming with async and await

Name change TcAdsClient --> AdsClient

This should simply document that there is another implemenation. Just rename the class instance.

Version 4.X

TcAdsClient client = new TcAdsClient()

Version 5.X

AdsClient client = new AdsClient()

Marshalling of byte[] and missing AdsStream class.

Newer .NET implementations have more efficient possiblities to exchange memory data between software layers and classes (see Memory- and span-related types ).

All API interface methods that use the combination of parameters (bytes, offset, length) or AdsStream

Version 4.X

public int TcAdsClient.Read(uint indexGroup,uint indexOffset,AdsStream dataStream)

Version 4.X

public int TcAdsClient.Write(uint indexGroup,uint indexOffset,AdsStream dataStream)

or

Version 4.X

public int TcAdsClient.Read(uint indexGroup,uint indexOffset,byte[] bytes, int offset, length)

Version 4.X

public int TcAdsClient.Write(uint indexGroup,uint indexOffset,byte[] bytes, int offset, length)

are changed like this:

Version 5.X

public int AdsClient.Read(uint indexGroup,uint indexOffset,Memory<byte> buffer)

Version 5.X

public int AdsClient.Write(uint indexGroup,uint indexOffset,ReadOnlyMemory<byte> buffer)

With this change a lot of interfaces will look much cleaner and act more efficient because of less array copy operations.

Handles are defined as uint type.

Handles are now streamlined consistently as uint type instead of int.

Version 4.X

public int TcAdsClient.CreateVariableHandle(string symbolPath)

Version 5.X

public uint AdsClient.CreateVariableHandle(string symbolPath)

Notification parameters bundled in one setings class.

Version 4.X

public int AddDeviceNotification(string symbolPath, AdsStream dataStream, int offset, int length, AdsTransMode transMode, int cycleTime, int maxDelay,Object userData)

Version 4.X

public int TcAdsClient.AddDeviceNotification(string symbolPath, AdsStream dataStream, int offset, int length, AdsTransMode transMode, int cycleTime, int maxDelay, Object userData)

The new parameterset simply needs the (byte) size of the transfered data instead of AdsStream, offset and length. Furthermore transMode, cycleTime and maxDelay are bundled in the NotificationSettings object.

Version 5.X

public uint AdsClient.AddDeviceNotification(string symbolPath,int dataSize, NotificationSettings settings, object userData)