The new C# API

Find and share HowTos to various installations / configurations!
Search

Post Reply
13 posts • Page 1 of 2
jcbaar
Posts: 34
Joined: Fri Sep 02, 2011 12:20 pm

The new C# API

Post by jcbaar »

I am running some experiments using the new C# API from WinCC OA 3.19 and I am probably misunderstanding some of the ideas behind the new API.

What I am trying to do is set three separate single DP value connects (so not a single multi value connect) using the ObserveDpValueAsync() extensions method on IOaProcessValues. This call returns a IAsyncEnumerable<ObserveSingleDpValueEventArgs>. No problems so far however when I iterate one of the IAsyncEnumerable's the iteration blocks until an actual event (hotlink) occurs on the observed DPE.

Unless I missed something obvious there does not seem to be a way for me to check if any data is present in the IAsyncEnumerable before actually trying to process it to prevent a blocking call.

Now I can start separate threads or tasks to handle each DP connection but that seems very wasteful to me.

What is the preferred way to handle multiple separate DP connects, query connects, events using the new API from a single thread?

Regards,
Jan

User avatar
kilianvp
Posts: 443
Joined: Fri Jan 16, 2015 10:29 am

Re: The new C# API

Post by kilianvp »

You have to make three separate single DP value connects. Otherwise it does not work. Or you have one with several and check in the callback which DP has delivered the value.

The C# Api uses only the C++ API. Everything you can't do under CTRL/C++ doesn't work in C# either. Therefore it is quite normal that ObserveSingleDpValueEventArgs blocks until a value is received.

Regards,
Kilian

jcbaar
Posts: 34
Joined: Fri Sep 02, 2011 12:20 pm

Re: The new C# API

Post by jcbaar »

Thanks for the information. I am aware that I have to make three separate connects however I want to handle their callbacks without having to spawn three separate threads.

I have worked around my issue by implementing a simple class like this:

Code: Select all

internal class AsyncDpObserver 
    {
        private readonly IOaProcessValues processValues;
        private IObservable<ObserveSingleDpValueEventArgs>? observer;
        private Func<ObserveSingleDpValueEventArgs, Task>? observerFunc;

        public AsyncDpObserver(IOaProcessValues processValues)
        {
            this.processValues = processValues;
        }

        public void Subscribe(string path, Func<ObserveSingleDpValueEventArgs, Task> observerFunc, bool initialValue = false, CancellationToken token = default)
        {
            if (this.observerFunc is null)
            {
                this.observerFunc = observerFunc;
                this.observer = processValues.ObserveDpValue(new DpIdentOrPath(path), initialValue);
                this.observer.Subscribe(HandleValueChange, token);
            }
        }

        private void HandleValueChange(ObserveSingleDpValueEventArgs e)
        {
            if (this.observerFunc is not null)
            {
                Task.Run(async () => await observerFunc(e));
            }
        }
    }
this will allow me to subscribe and asynchronously handle the hotlink callbacks like this without having to worry about blocking calls...

Code: Select all

	IOaProcessValues processValues;
	...
	
	var dpconnect1 = new AsyncDpObserver(processValues);
	var dpconnect2 = new AsyncDpObserver(processValues);
	
	dpconnect1.Subscribe( "data.point.element1", (e) =>
	{
		// handle dp value change 1
	});

	dpconnect2.Subscribe( "data.point.element2", (e) =>
	{
		// handle dp value change 2
	});
I've implemented a similar pattern for some of the manager events. Perhaps in doing it like this I still spawn threads to handle the hotlinks but this way I let the API handle that for me. I suspect the API can do this way more efficient for me and this keeps my code simple and testable and it plays nice with dependency injection.

Regards,
Jan

User avatar
leoknipp
Posts: 2926
Joined: Tue Aug 24, 2010 7:28 pm

Re: The new C# API

Post by leoknipp »

If you want to know how to use the WinCC OA API you can attend a WinCC OA training module. Please have a look at the links to get more information:
https://www.winccoa.com/support/training.html

https://www.winccoa.com/downloads/detai ... 85d44cc566

Best Regards
Leopold Knipp
Senior Support Specialist

jcbaar
Posts: 34
Joined: Fri Sep 02, 2011 12:20 pm

Re: The new C# API

Post by jcbaar »

What is the point of suggesting me to take a training module? Is asking a question about something that was released a few days ago not allowed without first having followed a WinCC OA training module?

A bit disappointing this...

Regards,
Jan

User avatar
leoknipp
Posts: 2926
Joined: Tue Aug 24, 2010 7:28 pm

Re: The new C# API

Post by leoknipp »

It was just the information that there are specific training modules available for the WinCC OA API.
The C# API is part of WinCC OA since several versions. This feature is not completely new in WinCC OA 3.19.

Please keep in mind that the WinCC OA Portal is a communication channel for the WinCC OA users worldwide to share information. It is not meant as substitution of the common WinCC OA Support.

Best Regards
Leopold Knipp
Senior Support Specialist

User avatar
kilianvp
Posts: 443
Joined: Fri Jan 16, 2015 10:29 am

Re: The new C# API

Post by kilianvp »

The API "documentation" has been virtually non-existent for several versions and the simplest functions are missing. Therefore, you have to use the internal functions that you should not use.

Always referring to the training when asking questions does not change the above mentioned problems.

Regards,
Kilian

User avatar
clicht
Posts: 24
Joined: Tue Aug 03, 2010 8:11 am

Re: The new C# API

Post by clicht »

The basic .NET API documentation is available at: <WinCC OA Inst Directory>\api.net\docu
It describes some ideas and concepts but is not that detailed.

Regarding observing DP values:
IAsyncEnumerable is one part of the task based asynchronous pattern of .NET.
The main benefit of both techniques is that all operations follow the pull-principal.
This means that the calling context is by definition unaware of internal threads.
By the way: This was a big problem with legacy C# API, where the client code in the callback was blocking all DP subscriptions.
As we use both concepts on our .NET API you should get familiar with it if you are not already.
Links:
https://docs.microsoft.com/en-us/dotnet ... ming-model
https://docs.microsoft.com/en-us/archiv ... n-csharp-8

Regarding your use case:
First of all you should ask yourself: Is it really necessary to have all 3 values in the same calling context?
Maybe you don't need it and you can solve your overall usecase differently.

For me it is hard to answer your question, because the answer depends on the overall usecase and the style your application is designed.
A principle that helps me in design of applications: everything is asynchronous, everything is parallel.

If you really need everything in same calling context there are also multiple ways to solve it.
The question is: How can I combine multiple IAsyncEnumerable streams?
That is the point where you leaf the responsibility of this portal, but I don't want you keep alone.

One of the things you can do by your own is to use a Channel, where you write the result of the ObserveDpValue streams in.
The result of the channel is a combined IAsyncEnumerable stream.
Link: https://learn.microsoft.com/en-us/dotne ... s/channels

For IAsyncEnumerable are also iterators available. Depending on your usecase you can use them in combined usage.
For a combined usage I found following on the internet:
https://itnext.io/merging-concurrent-ia ... 393005c6ae
At least it describes a similar situation, then yours.

One further idea is to use reactive extensions. I'm also not a specialist here but data processing is the main goal of this technology.
The WinCC OA .NET API provides some extension methods in the ETM.WCCOA.Services.Extensions.Reactive namespace, which return objects which can be used with reactive extensions.
Links:
https://reactivex.io/
https://github.com/dotnet/reactive

Last, but not least you can (but I don't recommend) use the legacy way of DP subscriptions.
There are extension methods available in ETM.WCCOA.Manager.Services namespace.

wenjie.meng
Posts: 4
Joined: Tue Dec 20, 2022 5:03 am

Re: The new C# API

Post by wenjie.meng »

any plans provide C# API on Linux? use .NET 6 or later?

User avatar
leoknipp
Posts: 2926
Joined: Tue Aug 24, 2010 7:28 pm

Re: The new C# API

Post by leoknipp »

Please have a look at the presentation of new features in WinCC OA 3.19.
https://www.winccoa.com/downloads/detai ... ce90f081dd

Best Regards
Leopold Knipp
Senior Support Specialist

Post Reply
13 posts • Page 1 of 2