2013-04-16 3 views
0

Так что в моем приложении у меня есть кнопка, которая разговаривает с lib, которая загружает некоторые данные из Интернета и фильтрует его. Когда приложение делает это, экран зависает, и он смотрит на пользователя, как приложение разбилось. Но это не так, потому что он загружает данные.Показывать spinner в MonoTouch при загрузке данных

Вот мой код:

GetDetailsBtn.TouchUpInside += (sender, e) => { 

    var defaults = NSUserDefaults.StandardUserDefaults; 

    if (RefNr.Text != string.Empty && RefNr.Text != null) { 

     FilteredDataRef = _FetchingData.getTrackTraceData (defaults.StringForKey ("SecurityToken"), RefNr.Text); 

     if (FilteredDataRef == null) { 
      UIAlertView InvalidAlert = new UIAlertView ("Reference number invalid", "The reference number that you have entered is not linked to the current security code. You can change your security code in the settings.", null, "OK", null); 
      InvalidAlert.Show(); 

     } else { 
      FilteredDataReceived = _FetchingData.FilteringOnReceived (FilteredDataRef); 

      FilteredDataPlanned = _FetchingData.FilteringOnPlanned (FilteredDataRef); 

      FilteredDataLoadingETA = _FetchingData.FilteringOnLoadingETA (FilteredDataRef); 

      FilteredDataLoadingFinal = _FetchingData.FilteringOnLoadingFinal (FilteredDataRef); 

      FilteredDataUnloadingETA = _FetchingData.FilteringOnUnloadingETA (FilteredDataRef); 

      FilteredDataUnloadingFinal = _FetchingData.FilteringOnUnloadingFinal (FilteredDataRef); 

      this.PerformSegue (MoveToTrackTraceDetailsSegue, this); 

      //foreach (string s in FilteredDataPlanned) 
      // Console.WriteLine (s); 

     } 

    } else { 
     UIAlertView InvalidAlert = new UIAlertView ("Reference number cannot be empty", "You did not provide a reference number. We need your reference number to trace identify the shipment you would like to trace.", null, "OK", null); 
     InvalidAlert.Show(); 
    } 
}; 

Загрузка данных:

public IEnumerable<string> getTrackTraceData (string securityCode, string referenceNumber) 
{ 
    WebRequest request = WebRequest.Create ("http://plex.janssen1877.com/app/life/" + securityCode); 

    HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

    Stream dataStream = response.GetResponseStream(); 

    StreamReader reader = new StreamReader (dataStream); 

    string FetchedData = reader.ReadToEnd(); 

    reader.Close(); 

    dataStream.Close(); 

    response.Close(); 

    var FetchingDataItems = FetchedData.Split (new char[] { '\n' }); 

    if (FetchingDataItems != null) { 
     var filteredResult = FetchingDataItems.Where (x => x.Contains (referenceNumber)); 

     return filteredResult; 
    } else { 
     return null; 
    } 
} 

Теперь я хочу использовать компонент под названием BTProgressHUD. Это просто причудливый прядильщик. Я подумал, что если бы я положил BTProgressHUD.show(); в начало действия кнопки и BTProgressHUD.Dismiss(); на кнопку, которая будет отображаться при загрузке и увольнении после ее завершения.

Это не тот случай. Он очень быстро отображается в новом контроллере представления и снова увольняется за секунду. Что я делаю не так?

РЕДАКТИР Exemple:

public IEnumerable<string> getTrackTraceData (string securityCode, string referenceNumber) 
     { 


      string url = string.Format ("http://plex.janssen1877.com/app/life/" + securityCode); 

      HttpWebRequest HttpRequest = (HttpWebRequest)WebRequest.Create (url); 

      string FetchedData = new StreamReader (HttpRequest.GetResponse().GetResponseStream()).ReadToEnd(); 


      var FetchingDataItems = FetchedData.Split (new char[] { '\n' }); 

      if (FetchingDataItems != null) { 
       var filteredResult = FetchingDataItems.Where (x => x.Contains (referenceNumber)); 

       return filteredResult; 
      } else { 
       return null; 
      } 


     } 
+0

Выполняется загрузка в асинхронном режиме? Или вы используете загрузку в основном потоке? Если последнее не подходит, возможно, загрузка выполняется очень быстро, но это правильное поведение. –

+0

@flexaddicted Я использую простой HTTP-запрос для загрузки.Я никогда не использовал async раньше, так как я только начал программировать. См. Мое редактирование для кода загрузки. –

ответ

3

Флориан,

Согласно .NET документации и HttpWebRequest GetResponse. How to wait for that response? вам необходимо выполнить загрузку (и, возможно, синтаксический) в асинхронном моды.

Поведение вашего фактического приложения верное. Когда вы выполняете запрос синхронизации в основном потоке, вы замораживаете приложение, и, следовательно, элементы пользовательского интерфейса не обновляются. Основной поток обрабатывает исполнение в серийном режиме.

Чтобы избежать этого, у вас есть два разных решения. С одной стороны, вам нужно перейти к асинхронному запросу. С другой стороны, вы можете создать фоновый поток (другой путь выполнения) с запросом синхронизации. Я предпочитаю первое. Так, например, после запуска асинхронного запроса покажите индикатор. Когда вы закончите (в обратном вызове), отпустите индикатор и выполните сеанс.

Например, вы можете узнать следующее, как это сделать: How to use HttpWebRequest (.NET) asynchronously?.

Чтобы понять, как работает основная нить (и цикл цикла), я предлагаю прочитать около The pogo stick of NSRunLoop.

Надеюсь, что это поможет.

Редактировать

Вы должны использовать шаблон следующего (источник How to use HttpWebRequest (.NET) asynchronously?):

HttpWebRequest webRequest; 

void StartWebRequest() 
{ 
    webRequest.BeginGetResponse(new AsyncCallback(FinishWebRequest), null); 
} 

void FinishWebRequest(IAsyncResult result) 
{ 
    webRequest.EndGetResponse(result); 
} 
+0

Тогда я пойду с асинксом. Правильно ли это: http://pastebin.com/9HNCWb3a –

+0

@florian, пожалуйста, отредактируйте свой ответ и введите код –

+0

См. Мои изменения для кода :) –

1

Это звучит, как вы пытаетесь сделать все это в том же потоке, как ваш пользовательский интерфейс, поэтому ваше приложение зависает и ждет завершения обработки, не показывая ничего. Я бы выполнил эту операцию загрузки в каком-то фоном. Тогда я не уверен в Mono, но обращаюсь к основному потоку до и после, покажу и отклоняю ваш компонент загрузки.

Смежные вопросы