I am building an application for both iOS and Android using Xamarin cross platform. I have one project called "Core", and then one for iOS and one for Android.
In the shared "Core" project I want to show a loading animation that I made, while fetching the current location from the device. I can get my locationWatcher, start it, and call LocationWatcher.CurrentPosition directly, but since it has just started watching for location updates, it hasn't yet had time to get any location.
My solution to this is to wait 2 seconds after starting it and then get the location. However I don't want to wait asynchroneously, I want the UI to be locked while waiting. This is because the user should not be able to do anything until current position os known.
I currently achieve this by having a loop:
DateTime startTime = DateTime.Now();
while ( (DateTime.Now() - startTime).TotalMilliseconds() < 2000) {
//Locking the UI here, but it's what I want so it's ok.
}
This seems like an ugly 'hack' for something that in Java would simply be "Thread.sleep(2000)"
Is there a better way of doing this?
The multiplatform way with Xamarin Forms would be to
await Task.Delay(ms);
Edit:
After reading that you really want to block the mainthread heres the multiplatform way to block a Thread:
Task.Delay(ms).Wait()
Blocking the UI thread is bad practice, since among other things it could cause the device to mark the app as "not responding". You are also not guaranteed that the position will have been determined in two seconds, so in the best case your suggestion is only a partial fix.
What you'll really want to do is to block UI input by disabling the possibility to give input (there should be methods to disable your UI elements) and then see if there's a callback from the geolocation service when it has determined your location. In the callback, re-enable the UI elements. If such a callback does not exist, perform the location lookup synchronously on the UI thread with RunOnUIThread/InvokeOnMainThread, so that the thread is blocked only until it returns.
If you want to go ahead with your solution anyway,
RunOnUiThread(() => Thread.Sleep(2000));
should do the trick, but I really recommend against doing that. On iOS, you'll have to do
InvokeOnMainThread(() => Thread.Sleep(2000));
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