ArcGIS Pro 3.7 API Reference Guide
ArcGIS.Core.Data.Realtime Namespace / RealtimeCursor Class / MoveNext Method
Example

In This Topic
    MoveNext Method (RealtimeCursor)
    In This Topic
    Advances to the next RealtimeRow in this RealtimeCursor. This method can be called on any thread.
    Syntax
    Public Function MoveNext() As Boolean
    public bool MoveNext()

    Return Value

    true if the cursor has successfully advanced to the next row; false if the cursor has passed the end of the collection.
    Exceptions
    ExceptionDescription
    A geodatabase-related exception has occurred.
    Remarks
    The RealtimeCursor can only advance sequentially forward. To move the cursor back to the beginning, you will have to reexecute the search to obtain a new row cursor.
    Example
    Search And Subscribe for Streaming Data
    {
      // Note: call within QueuedTask.Run()
      {
        //query filter can be null to search and retrieve all rows
        //true means recycling cursor
        using (var rc = streamLayer.SearchAndSubscribe(qfilter, true))
        {
          //waiting for new features to be streamed
          //default is no cancellation
          while (rc.WaitForRowsAsync().Result)
          {
            while (rc.MoveNext())
            {
              using (var row = rc.Current)
              {
                //determine the origin of the row event
                switch (row.GetRowSource())
                {
                  case RealtimeRowSource.PreExisting:
                    //pre-existing row at the time of subscribe
                    continue;
                  case RealtimeRowSource.EventInsert:
                    //row was inserted after subscribe
                    continue;
                  case RealtimeRowSource.EventDelete:
                    //row was deleted after subscribe
                    continue;
                }
              }
            }
          }
        }//row cursor is disposed. row cursor is unsubscribed
    
        //....or....
        //Use the feature class instead of the layer
        using var rfc = streamLayer.GetFeatureClass();
        //non-recycling cursor - 2nd param "false"
        using (RealtimeCursor rc = rfc.SearchAndSubscribe(qfilter, false))
        {
          //waiting for new features to be streamed
          //default is no cancellation
          while (rc.WaitForRowsAsync().Result)
          {
            //etc
          }
        }
      }
    }
    Search And Subscribe With Cancellation
    {
      // Note: call within QueuedTask.Run()
      {
        //Recycling cursor - 2nd param "true"
        //or streamLayer.Subscribe(qfilter, true) to just subscribe
        using (var rc = streamLayer.SearchAndSubscribe(qfilter, true))
        {
          //auto-cancel after 20 seconds
          var cancel = new CancellationTokenSource(new TimeSpan(0, 0, 20));
          //catch TaskCanceledException
          try
          {
            while (rc.WaitForRowsAsync(cancel.Token).Result)
            {
              //check for row events
              while (rc.MoveNext())
              {
                using var row = rc.Current;
                //etc
              }
            }
          }
          catch (TaskCanceledException)
          {
            //Handle cancellation as needed
          }
          cancel.Dispose();
        }
      }
    }
    Explicitly Cancel WaitForRowsAsync
    {
      RealtimeCursor rc = null;
      bool SomeConditionForCancel = false;
    
      //somewhere in our code we create a CancellationTokenSource
      var cancel = new CancellationTokenSource();
      //...
    
      //call cancel on the CancellationTokenSource anywhere in
      //the add-in, assuming the CancellationTokenSource is in scope
      if (SomeConditionForCancel)
        cancel.Cancel();//<-- will cancel the token
    
      //Within QueuedTask we are subscribed! streamLayer.Subscribe() or SearchAndSubscribe()
      try
      {
        //TaskCanceledException will be thrown when the token is cancelled
        while (rc.WaitForRowsAsync(cancel.Token).Result)
        {
          //check for row events
          while (rc.MoveNext())
          {
            using var row = rc.Current;
            //etc
          }
        }
      }
      catch (TaskCanceledException)
      {
        //Handle cancellation as needed
      }
      cancel.Dispose();
    }
    Subscribe to Streaming Data
    {
      //Note: with feature class we can also use a System Task to subscribe and
      //process rows
      // Note: call within QueuedTask.Run()
      {
        // or var rfc = realtimeDatastore.OpenTable(name) as RealtimeFeatureClass
        using RealtimeFeatureClass rfc = streamLayer.GetFeatureClass();
        //non-recycling cursor - 2nd param "false"
        //subscribe, pre-existing rows are not searched
        using RealtimeCursor rc = rfc.Subscribe(qfilter, false);
        SpatialQueryFilter spatialFilter = new SpatialQueryFilter();
        //waiting for new features to be streamed
        //default is no cancellation
        while (rc.WaitForRowsAsync().Result)
        {
          while (rc.MoveNext())
          {
            using (var row = rc.Current)
            {
              switch (row.GetRowSource())
              {
                case RealtimeRowSource.EventInsert:
                  //getting geometry from new events as they arrive
                  Polygon poly = ((RealtimeFeature)row).GetShape() as Polygon;
    
                  //using the geometry to select features from another feature layer
                  spatialFilter.FilterGeometry = poly;//project poly if needed...
                  featureLayer.Select(spatialFilter);
                  continue;
                default:
                  continue;
              }
            }
          }
        }
        //row cursor is disposed. row cursor is unsubscribed
      }
    }
    Search Existing Data and Subscribe for Streaming Data
    {
      //Note we can use System Task with the Realtime feature class
      //for subscribe
    
      // Note: call within QueuedTask.Run()
      {
        using RealtimeFeatureClass rfc = streamLayer.GetFeatureClass();
        //non-recycling cursor - 2nd param "false"
        using RealtimeCursor rc = rfc.SearchAndSubscribe(qfilter, false);
    
        //waiting for new features to be streamed
        //default is no cancellation - use await in async method
        while (rc.WaitForRowsAsync().Result)
        {
          //pre-existing rows will be retrieved that were searched
          while (rc.MoveNext())
          {
            using RealtimeRow row = rc.Current;
            var row_source = row.GetRowSource();
            switch (row_source)
            {
              case RealtimeRowSource.EventDelete:
                //TODO - handle deletes
                break;
              case RealtimeRowSource.EventInsert:
                //TODO handle inserts
                break;
              case RealtimeRowSource.PreExisting:
                //TODO handle pre-existing rows
                break;
            }
          }
        }
        //row cursor is disposed. row cursor is unsubscribed
      }
    }
    Search And Subscribe With Cancellation 2
    {
      // Note: call within QueuedTask.Run()
      {
        using RealtimeFeatureClass rfc = streamLayer.GetFeatureClass();
        //Recycling cursor - 2nd param "true"
        using RealtimeCursor rc = rfc.SearchAndSubscribe(qfilter, true);
        //auto-cancel after 20 seconds
        var cancel = new CancellationTokenSource(new TimeSpan(0, 0, 20));
        //catch TaskCanceledException
        try
        {
          // Use await in async method
          while (rc.WaitForRowsAsync(cancel.Token).Result)
          {
            //check for row events
            while (rc.MoveNext())
            {
              using RealtimeRow record = rc.Current;
              // Process the record
            }
          }
        }
        catch (TaskCanceledException)
        {
          //Handle cancellation as needed
        }
        cancel.Dispose();
      }
    }
    Requirements

    Target Platforms: Windows 11 Home, Pro, Enterprise (64 bit)

    ArcGIS Pro version: 3.0 or higher.
    See Also