Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sleep thread in Xamarin android and ios?

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?

like image 400
JavaDevSweden Avatar asked Nov 20 '15 09:11

JavaDevSweden


2 Answers

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()
like image 160
Michiluki Avatar answered Nov 15 '22 11:11

Michiluki


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));
like image 42
Geir Smestad Avatar answered Nov 15 '22 11:11

Geir Smestad