Asynchronous Silverlight 4 Призыв к World of Warcraft Armore Treaking XML в C #
-
04-10-2019 - |
Вопрос
Я застрял на этом все выходные и не потерпел неудачу!
Пожалуйста, помогите мне кого ждать мое здравомыслие!
Ваша задача
Для моего первого приложения 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
. Отказ Что касается подключения к Интернету и задержкам, поскольку операция возникает в другой поток, пользовательский интерфейс не замерзнет. Вы можете рассмотреть возможность отображения анимации погрузки или что-то еще.