How to loop a C# ARGGIS asynchronous method (Check post for the method code)

79 views Asked by At

I am using the arcGIS SDK in C# to search for addresses. What i would like to do is search for multiple addresses and then executing a method when all the addresses are found. This will most likely be achieved by using a loop.

Here is the code to find an address on the map:

public async void searchSubjectAddress(string sAddress)
{
    var uri = new Uri("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer");

    var token = string.Empty;
    var locator = new OnlineLocatorTask(uri, token);

    var info = await locator.GetInfoAsync();

    var singleAddressFieldName = info.SingleLineAddressField.FieldName;

    var address = new Dictionary<string, string>();

    address.Add(singleAddressFieldName, sAddress);

    var candidateFields = new List<string> { "Score", "Addr_type", "Match_addr", "Side" };

    var task = locator.GeocodeAsync(address, candidateFields, MyMapView.SpatialReference, new CancellationToken());

    IList<LocatorGeocodeResult> results = null;
    try
    {
        results = await task;

        if (results.Count > 0)
        {
            var firstMatch = results[0];
            var matchLocation = firstMatch.Location as MapPoint;

            Console.WriteLine($"Found point: {matchLocation.ToString()}");
            MyMapView.SetView(matchLocation);                    
        }

    }
    catch (Exception ex)
    {
        Console.WriteLine("Could not find point");
        var msg = $"Exception from geocode: {ex.Message} At address: {sAddress}";
        Console.WriteLine(msg);
    }
}

I am currently following this tutorial: https://developers.arcgis.com/net/10-2/desktop/guide/search-for-places.htm

I can find a single address, but the asynchronous tasks are a bit confusing. The code must be executed with the asynchronous tasks to function, so i cant change that.

To use this in an example: I want to get the distance between one property and several others. I only have access to the street addresses, so i use the above code to find the address and fetch the Geo-coordinates. Then i save those coordinates in a list for later use.

My problem is that when i want to execute the later methods, the async tasks are still running and my program executes the later methods regardless of whether the async methods are completed. When i change the method to a Task type instead of void, i usually end up with an endless wait with no tasks being accomplished.

I would like to know how i can loop the above method synchronously (let each new tasks only run when the older ones are finished) through a list of addresses and then run a method when all async tasks are finished. It would also be nice if the async tasks stop when a resulting address is found.

Help would be much appreciated!

1

There are 1 answers

3
dotMorten On

Change

public async void searchSubjectAddress(string sAddress)

to

  public async Task searchSubjectAddress(string sAddress)

Then whatever is calling searchSubjectAddress can await this call, so you know when it's complete. You might also consider making it return Task < SearchResult> instead so you can get the address sent back to the caller. Generally when you write "async void" you're setting yourself up for problems, so try to always make things "async Task" or "async Task< T>" instead.

On a side note: The v10.x releases have long been deprecated/unsupported, and you really should move to v100.8