Обработка потоков и веб-запросов в Windows Phone 7 - PullRequest
1 голос
/ 11 июля 2011

Как вы можете сделать фоновый веб-запрос, а затем обновить пользовательский интерфейс, но иметь весь код, который выполняет веб-запрос / анализ в отдельном классе, чтобы вы могли использовать его в нескольких местах? Я думал, что мог бы использовать методы классов в качестве обработчиков событий для класса BackgroundWorker, например

APIHelper mHelper = new APIHelper("http://example.com?foo=bar");
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork +=new DoWorkEventHandler(mHelper.GetResponse);
bw.RunWorkerCompleted +=new RunWorkerCompletedEventHandler(mHelper.HandleResponse);
bw.RunWorkerAsync();

где APIHelper имеет метод

public void GetResponse(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = (BackgroundWorker) sender;

    WebRequest request = HttpWebRequest.Create(this.URL);
    IAsyncResult result = (IAsyncResult)
                              request.BeginGetResponse(ResponseCallback, request);
}

но тогда я не знаю, как получить доступ к рабочему потоку из ResponseCallback, и, во всяком случае, сначала вызывается HandleResponse (очевидно). (Я попытался ввести result.AsyncWaitHandle.WaitOne();, но получаю ошибку NotSupportedException.) Однако я не могу понять, как сделать синхронный вызов веб-запроса. Я явно пытаюсь пойти по этому пути неправильно, но я понятия не имею, что такое правильный путь.


ETA:

Моя цель - быть в состоянии пойти:

  • пользователь нажимает (а) кнопку (и) (на разных страницах)

  • в потоке пользовательского интерфейса отображается «рабочее» сообщение (а затем ввод блокируется)

  • в фоновом потоке мой класс APIHelper делает соответствующий вызов API, получает ответ и передает его обратно в поток пользовательского интерфейса; Кажется, я могу сделать это, только запустив другой поток и ожидая его возврата, потому что нет синхронных веб-запросов

  • поток пользовательского интерфейса обновляется с возвращенным сообщением (и ввод продолжается как прежде)

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

Ответы [ 3 ]

2 голосов
/ 11 июля 2011

Мне потребовалось несколько попыток, прежде чем я обнаружил, что есть Dispatcher.

Во время методов BackgroundWorker * dowork и complete, которые вы можете вызвать:

this.Dispatcher.BeginInvoke(() =>
{
// UPDATE UI BITS
});

Я думаю, что Dispatcher доступно только в представлении.Поэтому я не уверен, могут ли методы существовать вне xaml.cs

Поместите все, что вы хотите обновить, в свой пользовательский интерфейс;при обновлении ObservableCollection вы должны обновить также свои элементы в Dispatcher.BeginInvoke тоже

Эта ссылка также может быть хорошо прочитана: http://www.windowsphonegeek.com/articles/All-about-Splash-Screens-in-WP7-ndash-Creating-animated-Splash-Screen

Обновление, чтобы помочьпримечания

Это просто грубая идея, обратите внимание ...

bw.DoWork +=new DoWorkEventHandler(DoWork);
bw.RunWorkerCompleted +=new RunWorkerCompletedEventHandler(Complete)

// At least I think the EA is DoWork....
public void DoWork(object sender, DoWorkEventArgs e)
{
        mHelper.GetResponse();
        this.Dispatcher.BeginInvoke(() =>
        {
              UIObject.Visibility Collapse.
        });

        // Wait and do work with response.
    });
}

public void Complete(object sender, RunWorkerCompleteEventArgs e)
{
        this.Dispatcher.BeginInvoke(() =>
        {
              UIObject.Visible ....
        });
}
0 голосов
/ 11 июля 2011

Это может быть полезно, если вы используете вспомогательный класс, который я разработал для целей WebDownload во время разработки WP7.

Я использую его в 2-3 приложениях WP7, и пока проблем нет.Дайте ему понять, поможет ли это.Вы можете получить класс из моего блога, связанного ниже:

http://www.manorey.net/mohblog/?p=17#content

[ПРИМЕЧАНИЕ] При работе с этим классом вам не нужно ничего запускать в фоновом режиме или в новой теме;все это обрабатывается асинхронно.

0 голосов
/ 11 июля 2011

Я бы поместил всю эту логику в модель представления, от которой наследуется модель представления каждой страницы.
Пусть страницы привязываются к свойствам модели представления (например, ShowLoading и т. Д.), Которые модель соответствующим образом обновляет.то есть перед выполнением веб-запроса и обратного вызова.

Поскольку вы не будете запускать код модели представления в потоке пользовательского интерфейса, вам также не нужно будет запускать отдельный BackgroundWorker, и вы сможете получить доступ к нему.свойства модели представления без вопроса.

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