iPhone эквивалент Application.DoEvents (); - PullRequest
2 голосов
/ 15 мая 2010

iPHone: мы используем MonoTouch, но ответы на Obj-C в порядке.

Мой одноэлементный объект домена занимает некоторое время, чтобы получить все данные, поэтому он выполняет внутренние части выборки в потоке.

Мне нужно сообщить UI, что домен готов. В настоящее время я делаю это. Есть ли способ лучше? В WinForms я бы вызвал Application.DoEvents () вместо Thread Sleep.

PlanDomain domain = PlanDomain.Instance ();
while (domain.IsLoadingData)
{
    Thread.Sleep (100);  //this is the main UI thread
}

TableView.Hidden = false;
TableView.Source = new TableSource (this);
TableView.ReloadData ();

Ответы [ 4 ]

6 голосов
/ 20 октября 2011

Просто для продолжения ответа зала ожидания, вот пример кода C #:

NSRunLoop.Current.RunUntil(DateTime.Now.AddMilliseconds(2000));

Это приостановит 2000 миллисекунд, но убедитесь, что пользовательский интерфейс обновляется. Я просто использовал это в некотором тестовом коде.

3 голосов
/ 15 мая 2010

Вообще говоря, вы хотите избежать DoEvents.Эквивалент iPhone в объективе-c выглядит примерно так:

[[NSRunLoop currentRunLoop] runUntilDate:[NSDate date]];
2 голосов
/ 20 мая 2010

Было бы лучше получить что-нибудь из AlertView (диалоговое окно загрузки), если вы не хотите выполнять фоновую загрузку.

Затем выполняется задача в отдельном Thread, к которому вы присоединяетесь, а затем закрываете диалоговое окно. Вот пример здесь , но он не имеет никакой многопоточности, но добавить его просто:

public class LoadingView : UIAlertView
{
    private UIActivityIndicatorView _activityView;

    public void Show(string title)
    {
        Title = title;
        Show();

        // Spinner - add after Show() or we have no Bounds.
        _activityView = new UIActivityIndicatorView(UIActivityIndicatorViewStyle.WhiteLarge);
        _activityView.Frame = new RectangleF((Bounds.Width / 2) - 15, Bounds.Height - 50, 30, 30);
        _activityView.StartAnimating();
        AddSubview(_activityView);

        // I haven't tested this, it should display the dialog still.
        Thread thread = new Thread(DoWork);
        thread.Start();
        thread.Join();

        Hide();
    }

    private void DoWork()
    {
        PlanDomain domain = PlanDomain.Instance ();
        while (domain.IsLoadingData)
        {
            // Maybe replace domain.IsLoadingData with an Event for when it finishes.
            // And then use a Mutex (WaitHandle) to communicate back
        }
    }

    public void Hide()
    {
        DismissWithClickedButtonIndex(0, true);
    }
}
1 голос
/ 15 мая 2010

Я бы посмотрел, можете ли вы использовать executeSelectorOnMainThread: переместите код Tableview в свой собственный метод и перезвоните к нему, когда закончите загрузку данных.

Делегаты также полезны в этом сценарии - заставьте ваш PlanDomain вызывать функцию делегата, когда это будет сделано.

Одновременно, если вы хотите что-то более обособленное, посмотрите на использование NSNotification s. Они наиболее полезны, когда код, который вы пишете, не должен знать или заботиться о том, что произойдет, когда он будет завершен - ему просто нужно объявить миру, что он выполнил свою работу. (Наиболее полезно, когда есть потенциально более чем одна вещь, которая может быть заинтересована в действии, когда она завершится.

В любом из них вы не хотите спать - просто дайте рупору справиться с этим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...