Running PI AF Service 18.104.22.16839
Background: We have a very simple AF model - no hierarchies - just a set of Element templates and Attributes. We are pulling in data from external web services on a continual basis, and using the AF SDK from C# code to both update the PI data as well as maintain the simple AF model. We have multiple threads that are doing this.
On occasion, there will be new assets in the incoming data, and we need to add them to the AF model and create PI Points for the corresponding attributes. Because of this, I have to check with AF whether an element exists for every data record I process. Even after consolidating the incoming data, this still amounts to a continuous execute of AFDataBase.Elements["myElementName"];
Problem #1: Generally speaking, if an element does not exist, the call returns a null, and I use this an indication to create the element. However, I frequently get the .Net error "Index was outside the bounds of the array" - with the stack trace indicating perhaps a dozen AF steps involving collections, pages, etc. as it tries to return the element.
I have tried many patterns of AF object instantiation as well as using the AFDatabase.Refresh method, but continue get the fault on occasion. Although I can probably develop a lame workaround - by restating my service, and forcing a refresh of the AF SDK's caches, I much prefer to understand why this is happening and then hopefully instantiate and/or refresh in a more elegant manner. The objects I'm using are:
PISystems systems = new PISystems();
piSystem = systems.DefaultPISystem;
db = piSystem.Databases[DatabaseName];
Problem #2: As mentioned in the above scenario, when AFDataBase.Elements["myElementName"] returns a null, I create a new element using the code below. Generally it's fine. Sometimes I get an error (on CheckIn) that the element already exists (immediate after AFDataBase.Elements["myElementName"] returns a null). However, the big problem is that at times AF actually adds an element with the same name as one that's already actually there.
element = db.Elements.Add(resourceNameSpace, eTemplate);
AFDataReference.CreateConfig(element, false, null);
I suppose I can run periodic sweeps for duplicates and then delete those, but I'm hoping that getting a better understanding of AF caching etc will lead to a better solution.