2015-11-20 37 views
6

Buduję aplikację na system iOS i Android, korzystając z platformy krzyżowej Xamarin. Mam jeden projekt o nazwie "Core", a potem jeden na iOS i jeden na Androida.Jak spać wątek w Androidzie Xamarin i ios?

W udostępnionym projekcie "Core" chcę wyświetlić animację ładowania, którą zrobiłem, podczas pobierania bieżącej lokalizacji z urządzenia. Mogę pobrać mój locationWatcher, uruchomić go i zadzwonić bezpośrednio do LocationWatcher.CurrentPosition, ale ponieważ właśnie zaczął oglądać aktualizacje lokalizacji, nie miał jeszcze czasu, aby uzyskać dowolną lokalizację.

Moim rozwiązaniem jest odczekać 2 sekundy po uruchomieniu, a następnie uzyskać lokalizację. Jednak nie chcę czekać asynchronicznie, chcę, aby interfejs był zablokowany podczas oczekiwania. Dzieje się tak dlatego, że użytkownik nie powinien nic robić, dopóki nie zostanie rozpoznana obecna pozycja.

Obecnie to osiągnąć poprzez pętlę:

DateTime startTime = DateTime.Now(); 
while ((DateTime.Now() - startTime).TotalMilliseconds() < 2000) { 
    //Locking the UI here, but it's what I want so it's ok. 
} 

To wydaje się brzydki „włamać” do czegoś, co w Javie byłoby po prostu „Thread.Sleep (2000)”

tam jest lepszy sposób robienia tego?

+0

Obie odpowiedzi działają, ale jak napisano, jest to naprawdę ** złe ** praktyka e, aby zablokować główny wątek UI, pamiętaj, że nadmiarowe blokowanie interfejsu użytkownika może spowodować, że aplikacja zostanie zakończona przez system operacyjny, a nawet spowodować, że nie zostanie przesłana aplikacja. IMO, Umieść thumper na ekranie i wykonuj asynchroniczne połączenie ... – SushiHangover

+0

Świetne komentarze, postaram się nie blokować głównego wątku UI, ponieważ robiłem to głównie dlatego, że nie mogłem uruchomić animacji ładującej, użytkownicy kręcili dziko, podczas gdy powinni naprawdę tylko czekać na wyniki. Spróbuję wykonać tę pracę z "poczekaj na Task.Delay (ms)". – JavaDevSweden

Odpowiedz

4

wieloplatformową sposób z formularzami Xamarin byłoby

await Task.Delay(ms); 

Edit:

Po przeczytaniu, że naprawdę chcesz zablokować mainthread heres wieloplatformowy sposób blokowania wątku:

Task.Delay(ms).Wait() 
1

Blokowanie wątku interfejsu użytkownika jest złą praktyką, ponieważ między innymi może spowodować, że urządzenie oznaczy aplikację jako "nie odpowiada". Nie można również zagwarantować, że pozycja zostanie określona w ciągu dwóch sekund, więc w najlepszym razie Twoja sugestia jest jedynie częściową poprawką.

Co naprawdę chcesz zrobić, to zablokować wejście interfejsu użytkownika przez wyłączenie możliwości wprowadzania danych (powinny być metody wyłączania elementów interfejsu użytkownika), a następnie sprawdzić, czy jest odwołanie od usługi geolokalizacji, gdy ustali ona Twoja lokalizacja. W wywołaniu zwrotnym ponownie włącz elementy interfejsu użytkownika. Jeśli takie wywołanie zwrotne nie istnieje, wykonaj synchronizację lokalizacji w wątku UI za pomocą RunOnUIThread/InvokeOnMainThread, aby wątek był blokowany tylko do momentu, aż się zwróci.

Jeśli chcesz iść do przodu z roztworu tak,

RunOnUiThread(() => Thread.Sleep(2000)); 

powinno załatwić sprawę, ale naprawdę odradzam robić. Na iOS, musisz zrobić

InvokeOnMainThread(() => Thread.Sleep(2000));