Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CLGeocoder.ReverseGecode hangs after 50 requests

First my code:

private CLGeocoder _coder = new CLGeocoder();

private void TestWithTpl()
{
    Console.WriteLine("Test started");
    var testLocation = new CLLocation(52.268157,-1.4209);
    Task.Factory.StartNew(async () => 
    {
        for (var i=0; i < 100; i++)
        {
            Console.WriteLine("Starting iteration {0}", i);
            var res = await _coder.ReverseGeocodeLocationAsync(testLocation);
            Console.WriteLine(res[0].AdministrativeArea);
            Console.WriteLine("Finished iteration {0}", i);
        }
    });
    Console.WriteLine("Finished");
}

private void TestDefault()
{
    Console.WriteLine("Test started");
    var testLocation = new CLLocation(52.268157,-1.4209);
    Task.Factory.StartNew(() => 
    {
        for (var i=0; i < 100; i++)
        {
            Console.WriteLine("Starting iteration {0}", i);
            var res = _coder.ReverseGeocodeLocationAsync(testLocation).Result;
            Console.WriteLine(res[0].AdministrativeArea);
            Console.WriteLine("Finished iteration {0}", i);
        }
    });
    Console.WriteLine("Finished");
}

As you can see, TestWithTpl will make use of async and await while TestDefault just uses the Result of the ReverseGeocodeLocationAsync.

No matter which method of the both I use: The output will be something like this:

2013-10-11 12:05:54.882 AddressResolveTest[5290:a0b] Test started
Thread started: <Thread Pool> #3
Thread started: <Thread Pool> #4
2013-10-11 12:05:54.892 AddressResolveTest[5290:a0b] Finished
2013-10-11 12:05:54.897 AddressResolveTest[5290:6303] Starting iteration 0
2013-10-11 12:05:55.125 AddressResolveTest[5290:6303] England
2013-10-11 12:05:55.126 AddressResolveTest[5290:6303] Finished iteration 0
2013-10-11 12:05:55.127 AddressResolveTest[5290:6303] Starting iteration 1
...
2013-10-11 12:05:57.302 AddressResolveTest[5290:6303] Finished iteration 49
2013-10-11 12:05:57.302 AddressResolveTest[5290:6303] Starting iteration 50

After the last line nothing happens.

I don't know, why:

  1. "Finished" is written before the code is ready.
  2. The code always stops at request no. 50.
like image 350
Alexander Schmidt Avatar asked May 12 '26 02:05

Alexander Schmidt


1 Answers

  1. "Finished" should be printed at the start, at least for the TPL version, as StartNew() start a task in the background, and the execution continue. It shouldn't be the case for the "Default" version. could you check ?

  2. the problem is that StartNew() swallows exceptions. If you change your code like this:

Console.WriteLine("Test started");
var testLocation = new CLLocation(52.268157,-1.4209);
Task.Factory.StartNew(async () => 
    {
        try{
            for (var i=0; i < 100; i++)
            {
                Console.WriteLine("Starting iteration {0}", i);
                var res = await _coder.ReverseGeocodeLocationAsync(testLocation);
                Console.WriteLine(res[0].AdministrativeArea);
                Console.WriteLine("Finished iteration {0}", i);
            }
        }catch(Exception e){
            Console.WriteLine (e);
        }
    });
Console.WriteLine("Finished");

you'll be able to get the Exception with the message: The operation couldn’t be completed. (kCLErrorDomain error 2.)

Googling for this message gets you a lot of hits here on stackoverflow, e.g. 1 and 2. This answer even announce the same '50' limit you get.

At the end, I'd say Apple limit the amount of request you can do per minute, and even recommend you not to overuse the API:

Applications should be conscious of how they use geocoding. Here are some rules of thumb for using this class effectively:

Send at most one geocoding request for any one user action.

Hope it helps.

like image 55
Stephane Delcroix Avatar answered May 13 '26 14:05

Stephane Delcroix