Select to view content in your preferred language

proper handling of add-in methods called from within a queued task

118
1
4 weeks ago
KerryAlley
Frequent Contributor

Greetings!

I have several working Pro add-in buttons where the OnClick() methods contain single QueuedTasks that contain calls to public methods that I keep in an internal class "SharedMethods".  Because the public methods consistently return values as expected, I haven't used Async/Await or QueuedTasks in these methods, but now I want to create a more complex public method that explicitly runs asynchronously and returns type long (or anything other than void or a task). Are there any examples of this available? I thought that this post might be relevant: https://community.esri.com/t5/arcgis-pro-questions/unable-to-create-a-task-with-geometry/td-p/105544... , but I couldn't make a public method (async or not) return the value of the QueuedTask as suggested in that example.

First of all, do I have to make these public methods Async, or is calling them from within a QueuedTask sufficient? If they must be Async, how do I get these methods to return a value of type long instead of void or a task?

Or should I be taking another approach entirely to making my add-ins modular?

Thanks!

Here's my attempt at a public method:

 

 

public async static long GetContainedLegOid(FeatureLayer MapMember, Geometry shape, Int64 faid, string startEnd)
{
    return QueuedTask.Run(() =>
    {
        var FC = MapMember.GetFeatureClass();
        //var spatialFilter = new SpatialQueryFilter { FilterGeometry = shape, SpatialRelationship = SpatialRelationship.Overlaps };
        var spatialFilter = new SpatialQueryFilter { FilterGeometry = shape, SpatialRelationship = SpatialRelationship.Contains };
        //MessageBox.Show(rowCount.ToString());
        RowCursor Cursor = FC.Search(spatialFilter);


        if (Cursor.MoveNext())
        {
            // Only get Oid if a feature was found
            var Feature = (Feature)Cursor.Current;
            var oid = Feature.GetObjectID();
            if (Cursor.MoveNext())
            {
                // If another feature was found, give warning message
                MessageBox.Show(string.Format("Multiple NodeLegs found, check results"));
            }
            return oid;
        }
        else 
        {
            MessageBox.Show(string.Format("{0} NodeLeg of rdsmall arc with FAID =  {1} not found", startEnd, faid));
            return 0;
        }
      });
}

 

 

 

0 Kudos
1 Reply
GKmieliauskas
Esri Regular Contributor

Hi,

Declaration of your method must be:

        public static Task<long> GetContainedLegOid(FeatureLayer MapMember, Geometry shape, Int64 faid, string startEnd)

Call to you method:

        var oid = await GetContainedLegOid(mapMember, shape, faid, startEnd);

It is not good idea to use MessageBox inside QueuedTask.Run. For example, you can return -oid and check value after calling your method:

var oid = await GetContainedLegOid(mapMember, shape, faid, startEnd);
if(oid == 0) {
     MessageBox.Show(string.Format("{0} NodeLeg of rdsmall arc with FAID =  {1} not found", startEnd, faid));
}
else {
    if(oid < 0) {
        MessageBox.Show(string.Format("Multiple NodeLegs found, check results"));
        oid = -oid;
    }
}
0 Kudos