8 Replies Latest reply on Jan 21, 2015 3:09 PM by Dan Fishman

    Loading EventFrames into DataTable (.Net, C#, AFSDK)

    wpurrer

      Dear PI Developers Club,

       

      I have a question about the performance of loading eventframes into a datatable, to show it in a datagrid.

       

      Currently im using the AFEventFrames.FindEventFrames Function. It performs very well, but i only get the basic event-frame information very fast (starttime, endtime, name, guid,...)

      (500 Frames in about 400ms)

       

      So, what ist the best way, to load the complete event-frame (with all attribues).    (there are only attributes, what are configured within the Event-Frame Template)

       

      Currently, i'm iterating through each EventFrame and get the value of each Attribute. But this solution is very slow.

       

      Actually it needs about 45s to load 500 EventFrames with all their attribute-values (about 20 attributes per event).

       

      Is there any other function available for better performance? (like PI System Explorer. Loading EventFrames with all attributes does need a couple of ms)

        • Re: Loading EventFrames into DataTable (.Net, C#, AFSDK)
          dng

          Have you tried using the AFEventFrame.LoadEventFrames methods? These methods fully load the AFEventFrame objects from the server into the client. This will ensure that the event frames in the list are fully loaded to avoid a call to the server to load each of the event frames individually.

           

          You might also be interested in checking out these previous posts:

          Performance tests in getting EventFrames

          Re: Getting the value of an event frame attribute

          1 of 1 people found this helpful
            • Re: Loading EventFrames into DataTable (.Net, C#, AFSDK)
              wpurrer

              Thx for your input. I tried it. Attribute-Values are loaded very fast.

              But how to bring it into the DataGrid?

                • Re: Loading EventFrames into DataTable (.Net, C#, AFSDK)
                  dng

                  The AFEventFrame.LoadEventFrames method loads the specified list of AFEventFrame objects from the server into the client. You can then use the same AFEventFrame object list to bring data into the DataGrid. I am by no means an expert in DataGrid, but you can take a look at the following example in which I illustrate one way to load some event frame attribute values into a MS DataGrid using C#:


                              PISystems myPISystems = new PISystems();
                              PISystem myAF = myPISystems["DNG-AF2014"];
                              AFDatabase myDb = myAF.Databases["Dev Support"];
                              AFNamedCollectionList<AFEventFrame> myEfs = AFEventFrame.FindEventFrames(myDb, null, "EFGeneration*", AFSearchField.Name, true, AFSortField.StartTime, AFSortOrder.Ascending, 0, 100);
                              AFEventFrame.LoadEventFrames(myEfs);
                  
                              DataTable dt = new DataTable();
                              dt.Columns.Add("Event Frame", typeof(string));
                              dt.Columns.Add("Attribute", typeof(string));
                              dt.Columns.Add("Value", typeof(double));
                  
                              foreach (AFEventFrame ef in myEfs)
                              {
                                  foreach (AFAttribute att in ef.Attributes)
                                  {
                                      dt.Rows.Add(ef.Name, att.Name, att.GetValue().Value);
                                  }
                              }
                            
                              dataGridView1.DataSource = dt;
                  
                  

                   

                  Note that in the above example, all my event frame attributes are numeric.

                    • Re: Loading EventFrames into DataTable (.Net, C#, AFSDK)
                      wpurrer

                      yes... like I have written in my first comment... iterating through all frames and per frame through all attributes is really slow.

                      Loading about 1000 EvenFrames with about 25 Attributes per Frame needs about 40s.

                      To show those Frames in PI System Explorer it does take about 2s....

                        • Re: Loading EventFrames into DataTable (.Net, C#, AFSDK)
                          Dan Fishman

                          Daphne's code is the most efficient method to load the EF attribute values since the att.GetValue method will go to the local AF SDK Cache.  Basically, loading the EF into memory (LoadEVentFrames) will cache the values if the Event Frames have captured Values.  I'm wondering, do the EF have their values captured?  We have the property AreVAluesCaptured which might help you figure out if there are any EF without captured values. 

                           

                          Obtaining 3,300 attribute values (300 EF with 11 attributes) took 2.66 seconds on my system.   All EF have values captured.  For large collections I've used multiple threads to obtain the values.

                           

                           

                          Dan

                          • Re: Loading EventFrames into DataTable (.Net, C#, AFSDK)
                            dng

                            I have achieved some interesting results during performance testing. Even though the AFAttribute.GetValue method should go to the local AF SDK cache (with captured values), when I tried to use a bulk GetValue method (using the AFAttributeList), I achieve significant performance gain. My code snippet is below:

                             

                                        AFAttributeList attList = new AFAttributeList();
                                        foreach (AFEventFrame ef in myEfs)
                                        {
                                            attList.AddRange(ef.Attributes);
                                        }
                                        AFValues values = attList.GetValue();
                            
                                        int i = 0;
                                        foreach (AFEventFrame ef in myEfs)
                                        {
                                            foreach (AFAttribute att in ef.Attributes)
                                            {
                                                dt.Rows.Add(ef.Name, att.Name, values[i].Value);
                                                i++;
                                            }
                                        }
                            

                             

                            Can you try to see if you get better results using the AFAttributeList.GetValue Method?