зависание в пользовательском интерфейсе во время загрузки контента в WP7 - PullRequest
5 голосов
/ 13 августа 2011

Я новичок в кодировании WP7. Я ищу образец кода или руководствуюсь следующей задачей:

У меня было 3 html-страницы на удаленном сервере, и я хочу загрузить содержимое каждой страницы и разместить его на 3 различных панорамах (показать как текстовый блок).

Я написал 3 набора веб-клиента для загрузки html-страницы; это может быть показано как где это должно быть. Моя проблема заключается в том, что когда / во время загрузки поток пользовательского интерфейса "зависает" и не отвечает.

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

Это код, который я использую для загрузки HTML-страницы.

private async void GetNewsIndex(string theN)
    {
        string newsURI = newsURL + theN;
        string fileName = theN + "-temp.html";
        string folderName = "news";

        prgBar01.Visibility = System.Windows.Visibility.Visible;

        try
        {
            Task<string> contentDataDownloaded = new WebClient().DownloadStringTaskAsync(new Uri(newsURI));

            string response = await contentDataDownloaded;

            WriteTempFile(theN, response.ToString());

            string contentData = ProcessDataToXMLNews(fileName, folderName);

            WritenewsIndexXMLFile(newsIndexURI, folderName, contentData);

            DisplayNewsIndex();

        }
        catch
        {
            //
        }
    }

Я изменил приведенный выше код в соответствии с предложением Синх Фам , и он работал отлично, как и ожидалось. Но, поскольку мне нужно запустить 3 раза, чтобы загрузить страницу с разных источников одновременно; перерыв кода Есть идеи?

Ответы [ 5 ]

2 голосов
/ 13 августа 2011

Вы уверены, что пользовательский интерфейс зависает при загрузке, а не при обработке данных? Из вашего кода кажется, что вы делаете только

WriteTempFile(theN, response.ToString());

string contentData = ProcessDataToXMLNews(fileName, folderName);

WritenewsIndexXMLFile(newsIndexURI, folderName, contentData);

DisplayNewsIndex();

в потоке пользовательского интерфейса. Попробуйте вместо этого обернуть их в BackgroundWorker.

Редактировать: что-то вроде этого:

Edit2: поскольку ваша функция DisplayNewsIndex () вызывает изменения в пользовательском интерфейсе, она должна выполняться в потоке пользовательского интерфейса.

var bw = new BackgroundWorker();
bw.DoWork += delegate {
    WriteTempFile(theN, response.ToString());
    string contentData = ProcessDataToXMLNews(fileName, folderName);
    WritenewsIndexXMLFile(newsIndexURI, folderName, contentData);
    Deployment.Current.Dispatcher.BeginInvoke(() => {
        DisplayNewsIndex();
    });
};
bw.RunWorkerAsync();
2 голосов
/ 13 августа 2011

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

1 голос
/ 14 августа 2011

независимо от того, где вы запустили .webClient (), или он асинхронный, или нет (я сомневаюсь, что у вас есть другой вариант, кроме async в Windows Phone WebClient) "ЭТО ПОЛНОСТЬЮ РАБОТАЕТ НА РЕЗЬБЕ UI".

Вот почему ваш пользовательский интерфейс заблокирован. на самом деле это ошибка, так как другие также предлагают вместо этого использовать HttpWebRequest. Что я собираюсь добавить, так это ссылка ниже на мой пост в блоге, которая содержит класс Helper WebDownloader, который уменьшает все трудности и облегчает жизнь:

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

Единственное, что вам нужно сделать, это:

var downloader = new WebDownloader{ Url = "something" };
downloader.OnCompleted += (a, b) => { /*downloader.Result is ready!*/ };
downloader.OnFailed += (a, b) => { /*download failed!*/ };
downloader.Download();

у вас также есть возможность отменить задачу загрузки, вызвав ее следующим образом:

downloader.Cancel();
1 голос
/ 13 августа 2011

Загрузка завершена асинхронно. Но ваша проблема - обработка данных в потоке пользовательского интерфейса. Вы должны рассмотреть возможность сделать это в другом потоке.

0 голосов
/ 13 августа 2011

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

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