2010-05-23 2 views
0

Я застрял на этом все выходные и провалился несчастно!
Пожалуйста, помогите мне отбить мое здравомыслие !!Асинхронный Silverlight 4 вызов в World of Warcraft арсенал потокового XML в C#

Ваша задача

Для моего первого Silverlight приложения, я думал, что это было бы интересно использовать Мир Warcraft Оружейной к списку символов в моей гильдии. Это включает в себя создание асинхронного Silverlight (duh!) В WoW armory, основанный на XML. ПРОСТОЙ EH?

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

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

Мне не удалось получить ожидаемый возвращенный XML вообще.

Примечания:

  • Если браузер способен преобразовывать XML он будет делать это, в противном случае будут предоставлены HTML. Я думаю, что он проверяет UserAgent
  • Я опытный веб-разработчик asp.net C#, так что легко начинайте говорить о родном для Windows Forms/WPF
  • Я не могу установить параметр UserAgent в .net 4.0 - по какой-то причине, похоже, не является объектом объекта HttpWebRequest - я думаю, что она была доступна.
  • Silverlight 4.0 (3.0 создан как первоначально, прежде чем я обновил свою установку Silverlight до 4,0)
  • Создано с помощью C# 4.0
  • Пожалуйста, объясните, как будто вы разговариваете с веб-разработчик, а не собственно программирование лол!

Ниже приведен код - он должен вернуть XML из арсенала wow.

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? 
      } 

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

Thanks mucho! Дэн.

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

ответ

1

первых, 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 в потоке и использовать диспетчеру только для отправки обратно guildies в пользовательский интерфейс, чтобы избежать замораживания пользовательского интерфейса, если XML очень долго разбираться (не должно быть).

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

+0

Извините - этот код не компилируется. Можете ли вы опубликовать рабочий образец? Я пытаюсь заставить его работать, и больше кода, который не работает, еще больше подчеркнет меня :) 1. httpWebRequest не существует в ReqCallBack 2. Часть (Action)() => ShowGuildies (x) Я очень ценю ваша помощь, и этот последний бит звучит интересно - в то время как не должно быть много времени синтаксического анализа, мне также приходится справляться с временной задержкой и подключением к Интернету. Ура! –

+0

Кроме того, я видел много примеров, которые я пробовал и просто не работал. Для такого простого примера, используя ссылку выше, было бы здорово увидеть, как специалист заработает - все выходные - я сейчас безумный :) –

+0

Мне нужен cookie –