ArcGIS Pro 3.0 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 RealtimeRow Current {get;}
    Public ReadOnly Property Current As RealtimeRow
    Remarks
    If the real-time cursor has exhausted the queue (i.e., when MoveNext returns false), null is returned. Use WaitForRowsAsync(CancellationToken) 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
    await QueuedTask.Run(async () =>
    {
      //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 (await rc.WaitForRowsAsync())
        {
          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 (var rc = rfc.SearchAndSubscribe(qfilter, false))
        {
          //waiting for new features to be streamed
          //default is no cancellation
          while (await rc.WaitForRowsAsync())
          {
            //etc
          }
        }
      }
    });
    Search And Subscribe With Cancellation
    await QueuedTask.Run(async () =>
    {
      //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 (await rc.WaitForRowsAsync(cancel.Token))
          {
            //check for row events
            while (rc.MoveNext())
            {
              using (var row = rc.Current)
              {
                //etc
              }
            }
          }
        }
        catch (TaskCanceledException tce)
        {
          //Handle cancellation as needed
        }
        cancel.Dispose();
      }
    });
    Explicitly Cancel WaitForRowsAsync
    //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 (await rc.WaitForRowsAsync(cancel.Token))
      {
        //check for row events
        while (rc.MoveNext())
        {
          using (var row = rc.Current)
          {
            //etc
          }
        }
      }
    }
    catch (TaskCanceledException tce)
    {
      //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
    await QueuedTask.Run(async () =>
    {
      // or var rfc = realtimeDatastore.OpenTable(name) as RealtimeFeatureClass
      using (var rfc = streamLayer.GetFeatureClass())
      {
        //non-recycling cursor - 2nd param "false"
        //subscribe, pre-existing rows are not searched
        using (var rc = rfc.Subscribe(qfilter, false))
        {
          SpatialQueryFilter spatialFilter = new SpatialQueryFilter();
          //waiting for new features to be streamed
          //default is no cancellation
          while (await rc.WaitForRowsAsync())
          {
            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...
                    countyFeatureLayer.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
    await System.Threading.Tasks.Task.Run(async () =>
    // or use ... QueuedTask.Run()
    {
      using (var rfc = streamLayer.GetFeatureClass())
      {
        //non-recycling cursor - 2nd param "false"
        using (var rc = rfc.SearchAndSubscribe(qfilter, false))
        {
          //waiting for new features to be streamed
          //default is no cancellation
          while (await rc.WaitForRowsAsync())
          {
            //pre-existing rows will be retrieved that were searched
            while (rc.MoveNext())
            {
              using (var 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
    await QueuedTask.Run(async () =>
    {
      //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 (await rc.WaitForRowsAsync(cancel.Token))
          {
            //check for row events
            while (rc.MoveNext())
            {
              using (var row = rc.Current)
              {
                //etc
              }
            }
          }
        }
        catch (TaskCanceledException tce)
        {
          //Handle cancellation as needed
        }
        cancel.Dispose();
      }
    });
    Requirements

    Target Platforms: Windows 11, Windows 10, Windows 8.1

    See Also