5 Replies Latest reply on Aug 6, 2010 6:14 PM by spilon

    Problem with IEventPipe2.AddSignUp

    JanvanderVen

      Dear List,

       

       

       

      I am writing an SDK based application that monitors tags through a PointList's EventPipe.

       

      The number of tags increases during the use of the service. I provide a web service that allows other applications to subscribe to tags they are interested in. The problem is that when a new tag is monitored, the event is fired the same number of times as there are items in the PointList.

       

      I have a couple of fields in my C# class:

      private PISDK.PointList pointList = new PISDK.PointList();
      PISDK._DEventPipeEvents_Event _ptEvent;
      PISDK.IEventPipe2 _pipe;

      And the event:

      public event TriggerActivatedHandler TriggerActivatedEvent;

      The delegate is defined in an interface that my class implements:

      public delegate void TriggerActivatedHandler(string thing, object value, DateTime timeStamp);

      And these are used in response the subscription request, like this:

      public void Subscribe(string tag)
      {
          if (pointList.Count > 0)
          {
              // reuse the defined _pipe
              _pipe.AddSignUp(sdk.Servers[piserver].PIPoints[tag], null);
          }
          else
          {
              try
              {
                  pointList.Add(sdk.Servers[piserver].PIPoints[tag]);
              }
              catch (Exception e)
              {
                  Console.WriteLine(e.Message);
              }
              _pipe = (PISDK.IEventPipe2)pointList.Data.EventPipe;
              _ptEvent = (PISDK._DEventPipeEvents_Event)_pipe;
              _ptEvent.OnNewValue += new PISDK._DEventPipeEvents_OnNewValueEventHandler(_ptEvent_OnNewValue);
          }
      }

      Now, whenever one of the monitored tags fires, the _ptEvent assumes that there are as many listeners as there are points in the PointList.

       

      This is the event handler:

      void _ptEvent_OnNewValue()
      {
          if (this.TriggerActivatedEvent == null)
          {
              // if nobody listens we have to do nothing
              return;
          }
          if (_pipe.Count == 0)
          {
              return;
          }
          Array events = _pipe.TakeAll();
          foreach (PISDK.PIEventObject peo in events)
          {
              PISDK.PointValue pv = (PISDK.PointValue)peo.EventData;
              this.TriggerActivatedEvent(pv.PIPoint.Name, pv.PIValue.Value.ToString(), pv.PIValue.TimeStamp.LocalDate); // this is the function that fires too often?
          }
      }

      So, I get too many events.

       

      The behaviour is identical, if you first do a _ptEvent.OnNewValue -= to remove the previous handler, and then do a += is again on the updated PointList.

       

      I do not quite understand what is going wrong.

       

      Please advise.

       

      Kind regards,
      Jan van der Ven

       

       

        • Re: Problem with IEventPipe2.AddSignUp
          cescamilla

          I think it is firing precisly one event for each new value reported. Not regarding the number of tags or the number of listeners.

           

          You could be better off using "Take" instead of "TakeAll" for this configuration.

           

          This is normal behaviour, and it is due to the fact that the firing of this event is subject to the settings in the NotifyThreshold and MaxNotifyFrequency properties of the EventPipe.  These properties act as filters on the event firing.  By default the NotifyThreshold is set to a count of 1 and the MaxNotifyFrequency is set to 1000 milliseconds.  The NotifyThreshold represents the minimum number of items in the pipe necessary for the OnNewValue event to be fired. Since you have this set to 1 it will fire exactly once for each value in the queue.  MaxNotifyFrequency  is the minimum amount of time that must have elapsed since the last event firing for the OnNewValue event to be fired.  When a new item arrives in the EventPipe, it checks to see if the NotifyThreshold has been reached and if the MaxNotifyFrequency has been exceeded before firing the event.  These properties are useful for applications that use EventPipes that receive many items but want to process them only occasionally. Which is exactly what you want to do.

           

          In this regards I would recommend setting the NotifyThreshold to a high value (around 256 maybe, just to say a random number), and the MaxNotifyFrequency to the minimum amount of time you want the new values to arrive at. I tried using 256 and 1000 respectively and I only got one notification each second for any number of values between 1 and 256. For any number of tags and any number of listeners.

           

           

           

          You may want to add the following line just after it is assigned.

          _pipe.NotifyThreshold = 100;

           

           

          Note that this will effectively wait untill 100 events have arrived before firing the event.