Правильный способ отсрочки загрузки представления до завершения веб-запроса или другой длительной задачи - PullRequest
2 голосов
/ 09 января 2012

При выполнении веб-запроса или любой другой длительной задачи я должен делать это в отдельном потоке (назовем этот поток B), чтобы не блокировать пользовательский интерфейс. Но каков стандартный способ принятия мер по результатам после выполнения задачи?

Я уже придумал эти варианты:

1) Установите пользовательское событие, которое запускается в потоке B, когда запрос завершается, и что основной поток прослушивает и обрабатывает должным образом.

2) Когда запрос завершится, вызовите InvokeOnMainThread из потока B.

3) Передайте ссылку на ViewController при запуске потока B. А затем, когда веб-запрос завершится, выполните все необходимые действия на viewcontroller в самом потоке B.

Ответы [ 3 ]

3 голосов
/ 09 января 2012

Я использую ThreadPool для выполнения этих запросов.Преимущество состоит в том, что среда выполнения автоматически добавляет и удаляет потоки в зависимости от их использования, и вам не нужно управлять их жизненным циклом:

 class MyViewController : UIViewController {
     void PlusOne (string url, string username)
     {
          ThreadPool.QueueUserWorkItem (delegate {
              var wc = new WebClient ();
              wc.UploadString (url, "+1");
              BeginInvokeOnMainThread (delegate { PlusOneDone (username); });


     void PlusOneDone (string username)
     {
           Console.WriteLine ("Plus one completed for {0}", username);
     }
 }

В этом сценарии я использую несколько анонимных методов, используявложенные анонимные методы (или лямбды), вы можете легко распространять параметры (в данном случае «имя пользователя») из исходного потока, который вызывает PlusOne «в обратный вызов m

3 голосов
/ 10 января 2012

Другой альтернативой является использование класса System.Net.WebClient, который предоставляет API более высокого уровня (чем WebRequest и WebResponse) и который проще использовать должным образом (например, для минимизации выделения памяти, работы сразличное кодирование ...) и также предоставляет несколько простых = используемых Async методов.

Например WebClient.DownloadStringAsync метод и WebClient.OnDownloadStringCompleted событие.

1 голос
/ 09 января 2012

Я обычно вызываю метод, который выполняется в отдельном потоке с действием обратного вызова.

void StartRequest(Uri url, Action<T> callback) {
    using (var ns = new NSAutoReleasePool ()){
        // Do some work
        callback(T);
    }
}

С callback(T), имеющим доступ ко всему, что вы хотите манипулировать.

Вы можететакже посмотрите документацию о потоке TweetStation или MonoTouch.Dialog для примеров обратных вызовов ASync.

Конечно, вы можете использовать делегаты с той же целью, или события и т. д.... Вы на правильном пути!

...