ArcGIS Pro 3.0 API Reference Guide
ArcGIS.Core.Data.Realtime Namespace / RealtimeCursor Class / WaitForRowsAsync Method / WaitForRowsAsync() Method
Example

In This Topic
    WaitForRowsAsync() Method
    In This Topic
    Asynchronously waits for new rows to be available in the internal queue of this real-time cursor. The returned System.Threading.Tasks.Task will also complete if the state of this RealtimeCursor (see GetState) changes from RealtimeCursorState.Subscribed. This method can be called on any thread.
    Syntax
    public Task<bool> WaitForRowsAsync()
    Public Overloads Function WaitForRowsAsync() As Task(Of Boolean)

    Return Value

    A System.Threading.Tasks.Task that will complete once this cursor becomes unsubscribed or new rows are available in the internal queue of this real-time cursor. The returned System.Boolean value is false if this cursor is unsubscribed and there are no more rows to be read. Otherwise it's true.
    Exceptions
    ExceptionDescription
    A geodatabase-related exception has occurred.
    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();
      }
    });
    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
      }
    });
    
    Requirements

    Target Platforms: Windows 11, Windows 10, Windows 8.1

    See Also