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:
"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 ?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With