4 of 4 people found this helpful
PI SDK is announced for deprecation and we highly recommend to decide in favor of AF SDK with recent .NET development projects. Looking at your code, my impression is you are using AF SDK already but I wanted to make sure to point out PI SDK shouldn't be used.
The PIServer object becomes instantiated in the context of a specific (Windows) user account. If your code considers multiple instances in the same user context, the first created instance will be re-used. If you close the connection or dispose the object in one thread, this impacts other threads which may use the same instance. Your observation proofs this. Even worth, you may experience access violation exceptions when the PIServer instance becomes garbage collected because it becomes disposed in a thread but shortly after used in another thread. Please treat the PIServer object as a global object.
There is some overhead in establishing a connection and there is also a cache created whenever the server object becomes instantiated. In summary establishing a connection can be considered as a time consuming task and hence using a single instance per user account and application makes perfect sense to me. Can you indicate why you like to have each thread connecting individually?
Thank you for your replay. I do use the AF SDK, forgive my inaccuracy.
The reason I wanted to have each thread connecting individually to the pi sever is that currently my code is written in a way that whenever a thread receives an exception thrown from an AF SDK function, it initiates a disconnect from the pi server, reconnects and start it's work again.
therefore, I did not want that an exception thrown from one of the threads will disconnect all the other threads. I wanted the other threads to keep on working while the disconnected thread reconnects.
But, since now I understand that all threads have actually the same connection, I believe that what I have to do is check on each try-catch block what is the reason for the exception, in order to distinguish between a server-disconnection exception, and all other exceptions: so In case of disconnection exception all threads will initiate a stop process and disconnect, and in all other exceptions, the threads will not initiate disconnection, but continue their work.
This leads me to another question I will be glad to be clarified of:
What is the best way to check in a try-catch block if the exception was thrown because of a server disconnection or not?
Is the PIConnectionInfo.IsConnected property useful and reliable to be checked on the catch block? or maybe this property takes time to be set after a pi-server disconnection so that the information will not yet be updated in the catch block?
As suggested in this discussion from Dec 2016, concerning AFConnectionInfo.IsConnected property:
I believe that since I am checking a pi server connectivity in a catch block and after I make a call that hits the PI server, the PIConnectionInfo.IsConnected should be set to the updated server connection.
Would you agree?
1 of 1 people found this helpful
This other thread refers AFConnectionInfo.IsConnected property and you are dealing with PIConnectionInfo.IsConnected but the behavior is the same. The IsConnected property reports the latest known status of the connection and requires an operation accessing the server to become updated. Please note that not always the PIConnectionException bubles up to the surface which is a requirement to capture it with your try-catch block. Some of the methods e.g. those returning a collection like AFValues may have the exception within the collection.
The server objects like PISystem and PIServer are capable to detect and handle the connection status. If the connection is interrupted for some reason, they are able to re-establish the connection. However, if the connection is broken, read and write operations will fail and you need to assume that you will have to repeat them as soon as the connection is re-established. This is e.g. not the case if your application writes through PI Buffer Subsystem because PI Buffer Subsystem will queue failed write operations until the connection is back.
There are multiple reasons the connection to a server is breaking like the server being unresponsive or shut down, a piece of network hardware is failing or the network link simply being not stable. When thinking about addressing connection issues in code, it also makes sense to think about how different scenarios can be tested. A common mistake with testing buffering through PI Buffer Subsystem by detaching the network cable from an interface node. The problem here is that as soon as the network card becomes disconnected, Windows is taking down TCP/IP which causes the interface not being able to communicate to the local PI Buffer Subsystem instance. If you are interested, please see KB00300 - How do I simulate a PI Server shutdown to test buffering.
Can you indicate share some information what kind of application you are developing, what kind of connection issues you envision and how you plan to test those?
Usually, when foreseeing multiple parallel operation threads, this is due to performance considerations. AF SDK offers what we refer to as bulk calls. These are data reads or writes potentially involving multiple data items and / or covering time periods. Bulk calls reduce the amount of required calls to and from the server dramatically. The impact of network latency is reduced and hence bulk calls often outperform asynchronous operations. For sure if a bulk-operation fail due to connection issues, it may also be necessary to repeat them but the retry-handling may be simpler as with asynchronous methods.