ArcGIS Pro 3.7 API Reference Guide
ArcGIS.Core.Data.Realtime Namespace / RealtimeCursor Class / Current Property
Example

In This Topic
    Current Property (RealtimeCursor)
    In This Topic
    Gets the current RealtimeRow in this RealtimeCursor.
    Syntax
    Public ReadOnly Property Current As RealtimeRow
    public RealtimeRow Current {get;}
    Remarks
    If the real-time cursor has exhausted the queue (i.e., when MoveNext returns false), null is returned. Use RealtimeCursorBase.WaitForRowsAsync to wait until more rows are available or the cursor is unsubscribed. If a valid RealtimeRow is returned by this property, it should be Disposed.
    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