matthew.j.hampton

Are PISystem instances singletons? Are they thread-safe?

Discussion created by matthew.j.hampton on Jul 11, 2014
Latest reply on Jul 14, 2014 by David Hearn

Hi there,

 

I'm a little bit new to the AF SDK, and was caught out by some slightly unexpected behaviour. Because I intended to have different PISystem connections (credentials) for different aspects of the application, I was creating multiple instances of PISystems + PISystem, expecting them to be independent. However, disconnecting one instance of a particular PISystem, also disconnected (what I thought were) independent instances, but which turned out to be the same instance.

 

Please see this little unit test by way of explanation:

 
[TestMethod]
public void TestTwoPiConnections()
{
    //Create a connection to the default PI system for a particular user:
    PISystems pisystemsInstance1 = new PISystems();
    PISystem piSystemInstance1 = pisystemsInstance1.DefaultPISystem;
    NetworkCredential credentialInstance1 = new NetworkCredential(Config.getConfig().username, Config.getConfig().password);
    piSystemInstance1.Connect(credentialInstance1);
    Assert.IsTrue(piSystemInstance1.ConnectionInfo.IsConnected);

    //Try to create a new PIServer instance that happens to be for the default PI system and for the same user:
    PISystems pisystemsInstance2 = new PISystems();
    PISystem piSystemInstance2 = pisystemsInstance2.DefaultPISystem;
    NetworkCredential credentialInstance2 = new NetworkCredential(Config.getConfig().username, Config.getConfig().password);
    piSystemInstance2.Connect(credentialInstance2);
    Assert.IsTrue(piSystemInstance2.ConnectionInfo.IsConnected);

    //See if the objects are actually different objects:
    Assert.IsFalse(Object.ReferenceEquals(pisystemsInstance1, pisystemsInstance2));
    Assert.IsFalse(Object.ReferenceEquals(credentialInstance1, credentialInstance2));

    //The same PISystem instance is being returned, even though it is a different instance of PISystems:
    //(this is a little unexpected for me)
    Assert.IsTrue(Object.ReferenceEquals(piSystemInstance1, piSystemInstance2));

    //The result is that if I disconnect one, the other is disconnected as well:
    piSystemInstance1.Disconnect();
    Assert.IsFalse(piSystemInstance1.ConnectionInfo.IsConnected);
    //The second one is also disconnected! (this was the unexpected behaviour that caught me out):
    Assert.IsFalse(piSystemInstance2.ConnectionInfo.IsConnected);
}

 This has lead me to wonder what the intended usage pattern is:

 

1. Are PISystem instances for a particular server singletons? i.e. Should I just hold a static reference to them and reuse them all over the show, disconnecting only when my application terminates?

 

2. i.e. Is it safe to use the same PISystem object and related databases and elements in different threads?

 

Thanks for the help!

 

Matt Hampton

Outcomes