2013-06-06 3 views
1

У меня длинная работа, которую я хочу запустить синхронно (я рассмотрю позже асинхронный).Xamarin Loading Overlay Not Showing

Я использую код наложения здесь - http://docs.xamarin.com/recipes/ios/standard_controls/popovers/display_a_loading_message

Вот мой тестовый код -

public override void ViewDidAppear (bool animated) 
    { 
     base.ViewDidAppear (animated); 

     loadingOverlay = new LoadingOverlay (UIScreen.MainScreen.Bounds); 
     View.Add (loadingOverlay); 

     int i = 0; 
     while (i < 5000) 
     { 
      Console.WriteLine(i); 
      i++; 
     } 

     loadingOverlay.Hide(); 
    } 

Но первоначальное наложение не показывает, только Скрыть анимации после цикла в то время как завершается?

я могу произвести хак/обходной путь, как так -

public override void ViewDidAppear (bool animated) 
    { 
     base.ViewDidAppear (animated); 

     loadingOverlay = new LoadingOverlay (UIScreen.MainScreen.Bounds); 
     View.Add (loadingOverlay); 

     NSTimer nstimer = NSTimer.CreateScheduledTimer (1,() => { 

      int i = 0; 
      while (i < 5000) { 
       Console.WriteLine (i); 
       i++; 
      } 

      loadingOverlay.Hide(); 
     }); 
    } 

Но может кто-то пожалуйста, объясните мне, почему это происходит, и как писать код правильно так IOS рисует накладку на экран перед началом петля.

+0

Ваш первый пример блокирует поток пользовательского интерфейса. Второй пример запускает NSTimer в фоновом потоке, поэтому он не блокирует пользовательский интерфейс. – Jason

+0

Спасибо за подтверждение, что Джейсон, но есть ли другой способ сказать IOS обновить поток пользовательского интерфейса после добавления наложения до его блокировки? или это лучшее обходное решение? – WickedW

ответ

4

Вы блокируете поток пользовательского интерфейса, которого вы никогда не должны делать. Любая длинная работа должна выполняться в фоновом потоке, даже если вы хотите обработать ее синхронно.

С Xamarin.iOS альфа (с поддержкой асинхронной/ждать), ваш код будет выглядеть следующим образом:

public async override void ViewDidAppear (bool animated) 
{ 
    base.ViewDidAppear (animated); 

    loadingOverlay = new LoadingOverlay (UIScreen.MainScreen.Bounds); 
    View.Add (loadingOverlay); 

    await Task.Factory.StartNew (() => { 
     int i = 0; 
     while (i < 5000) 
     { 
      Console.WriteLine(i); 
      i++; 
     } 
    }); 

    loadingOverlay.Hide(); 
} 

Если у вас нет доступа к async/await, вы можете достичь того же результата с:

Task.Factory.StartNew (() => { 
     int i = 0; 
     while (i < 5000) 
     { 
      Console.WriteLine(i); 
      i++; 
     } 
    }).ContinueWith(task => InvokeOnMainThread(() => { loadingOverlay.Hide(); })); 

но это менее приятно (также проверьте скобки закрытия, я только что ввели этот код)

+0

Спасибо @StephaneDelcroix. Я пришел в версию без ожидания - }). ContinueWith (task => InvokeOnMainThread (() => {loadingOverlay.Hide();})); Пожалуйста, не стесняйтесь обновлять свой ответ, если это полезно. – WickedW

2

Добавить this Component в ваше приложение и сделать это. Не нужно заново изобретать колесо.

+0

, как это бывает, причина, по которой я задал этот вопрос, и написав этот тестовый код, заключается в том, что я использовал этот компонент, и он создавал ту же проблему с Show (..) - loop - ShowSuccessWithStatus(), только ShowSuccessWithStatus () Показано. Поэтому я удалил компонент из Q. – WickedW