Вопрос

Я застрял на этом все выходные и не потерпел неудачу!
Пожалуйста, помогите мне кого ждать мое здравомыслие!

Ваша задача

Для моего первого приложения Silverlight я подумал, что было бы интересно использовать World of Warcraft Armory, чтобы перечислить персонажей в моей гильдии. Это включает в себя изготовление асинронного от Silverlight (Duh!) К WOW Armore, которая основана на XML. Простой эх?

Посмотрите на эту ссылку и откройте источник. Вы увидите, что я имею в виду:http://eu.wowarmory.com/guild-info.xml?r=eonar&n=gifted. и талантливый

Ниже приведен код для получения XML (звонок для Showguildies, справится с возвращенным XML - я проверил это локально, и я знаю, что работает).

Мне не удалось вообще добраться ожидаемого XML.

Примечания:

  • Если браузер способен преобразовывать XML, он будет делать это, в противном случае HTML будет предоставлен. Я думаю, что это изучает пользователь
  • Я опытный веб-разработчик ASP.NET C # Так что легко, если вы начнете говорить о родных формах Windows / WPF
  • Похоже, я не могу установить настройку USERAGENT в .NET 4.0 - не так, кажется, не является свойством объекта httpwebrequest по какой-то причине - я думаю, что он был доступен.
  • Silverlight 4.0 (создан как 3.0 Первоначально, прежде чем я обновил мою установку Silverlight до 4.0)
  • Создан с использованием C # 4.0
  • Пожалуйста, объясните, как будто вы говорите с веб-разработчиком, а не надлежащим программированием LOL!

Ниже приведен код - он должен вернуть XML из WOW Armore.

private void button7_Click(object sender, RoutedEventArgs e)
{
   // URL for armoury lookup
                string url = @"http://eu.wowarmory.com/guild-info.xml?r=Eonar&n=Gifted and Talented";

                // Create the web request
                HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);

                // Set the user agent so we are returned XML and not HTML
                //httpWebRequest.Headers["User-Agent"] = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)";

                // Not sure about this dispatcher thing - it's late so i have started to guess.
                Dispatcher.BeginInvoke(delegate()
                {
                    // Call asyncronously
                    IAsyncResult asyncResult = httpWebRequest.BeginGetResponse(ReqCallback, httpWebRequest);

                    // End the response and use the result
                    using (HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.EndGetResponse(asyncResult))
                    {
                        // Load an XML document from a stream
                        XDocument x = XDocument.Load(httpWebResponse.GetResponseStream());

                        // Basic function that will use LINQ to XML to get the list of characters.
                        ShowGuildies(x);
                    }
                });
            }

            private void ReqCallback(IAsyncResult asynchronousResult)
            {
                // Not sure what to do here - maybe update the interface?
            }

Действительно надеюсь, кто-то там может помочь мне!

Спасибо Мучи! Дэн.

PS Да, я заметил иронию во имя гильдии :)

Это было полезно?

Решение

Первый, Dispatcher.BeginInvoke Нужно только тогда, когда вы находитесь в другой ните, чем в потоке пользовательского интерфейса (где происходит все Silverlight / WPF). На событии Click вы уже в потоке пользовательского интерфейса, поэтому нет необходимости называть это.

Второй, BeginGetResponse Это асинхронная операция, поэтому, когда она закончилась, она позвонит функции обратного вызова на другой ните, здесь ReqCallback. Отказ Это в этом методе, который вы можете позвонить EndGetResponse. Отказ Этот шаблон применяется к каждому BeginX / EndX, вы найдете в рамках.

Однако, поскольку вы находитесь в другом потоке, вам нужно будет использовать BeginInvoke отправить метод обратно в пользовательскую ниту.

Код будет выглядеть так:

private void button7_Click(object sender, RoutedEventArgs e) {
    string url = @"http://eu.wowarmory.com/guild-info.xml?r=Eonar&n=Gifted and Talented";
    HttpWebRequest httpWebRequest = (HttpWebRequest) WebRequest.Create(url);
    httpWebRequest.BeginGetResponse(ReqCallback, httpWebRequest);
}

private void ReqCallback(IAsyncResult asyncResult)
{
    HttpWebRequest httpWebRequest = (HttpWebRequest) asyncResult.AsyncState;
    using (HttpWebResponse httpWebResponse = (HttpWebResponse) httpWebRequest.EndGetResponse(asyncResult))
    {
        XDocument x = XDocument.Load(httpWebResponse.GetResponseStream());
        Dispatcher.BeginInvoke((Action) (() => ShowGuildies(x)));
    }
}

Обратите внимание, что вы также можете обработать XML в потоке и использовать диспетчеру только для отправки по Гулкам на UI, чтобы избежать замораживания пользовательского интерфейса, если XML очень длинный для анализа (не должен быть в случае).

Редактировать: Исправлен код. Вам нужно только реализовать ShowGuildies. Отказ Что касается подключения к Интернету и задержкам, поскольку операция возникает в другой поток, пользовательский интерфейс не замерзнет. Вы можете рассмотреть возможность отображения анимации погрузки или что-то еще.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top