非同期シルバーライト4 World of Warcraft ArmoryストリーミングXMLのC#への呼び出し
-
04-10-2019 - |
質問
私は週末を通してこれに立ち往生しており、惨めに失敗しました!
私の正気を取り戻すのを手伝ってください!!
あなたの挑戦
私の最初のSilverlightアプリケーションでは、World of Warcraft Armoryを使用してギルドのキャラクターをリストするのは楽しいと思いました。これには、Silverlight(Duh!)からXMLベースのWow Armoryへの非同期を作ることが含まれます。簡単なえ?
このリンクを見て、ソースを開きます。あなたは私が意味することを見るでしょう:http://eu.wowarmory.com/guild-info.xml?r = eonar&n=gifted そして才能
以下はXMLを取得するためのコードです(ShowGuildiesへの呼び出しは、返されたXMLに対処します - これをローカルでテストしましたが、それが機能することは知っています)。
私は期待されるXMLをまったく取得することができませんでした。
ノート:
- ブラウザがXMLを変換できる場合、そうしないとHTMLが提供されます。私はそれがユーザーエージェントを調べると思います
- 私はベテランのASP.NET Web開発者C#ですので、Windowsフォームのネイティブ / WPFのネイティブについて話し始めると簡単に進みます
- .NET 4.0でユーザーエージェント設定を設定できないようです - 何らかの理由でHTTPWebRequestオブジェクトのプロパティではないようです - 以前は利用可能だったと思います。
- Silverlight 4.0(Silverlightのインストールを4.0に更新する前に、元々3.0として作成)
- C#4.0を使用して作成されました
- 適切なプログラミングではなく、Web開発者と話しているかのように説明してください。
以下はコードです - WOW ArmoryからXMLを返す必要があります。
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?
}
そこにいる誰かが私を助けることができることを本当に願っています!
Muchoありがとう!ダン。
PSはい、私はギルドの名前で皮肉に気づいた:)
解決
初め、 Dispatcher.BeginInvoke
UIスレッド以外のスレッドを使用している場合にのみ必要です(Silverlight/WPFに関連するすべてが発生する場合)。クリックイベントでは、すでにUIスレッドにいるので、電話する必要はありません。
2番、 BeginGetResponse
非同期操作であるため、終了すると、別のスレッドでコールバック関数を呼び出します。 ReqCallback
. 。この方法に電話することができます EndGetResponse
. 。このパターンは、フレームワークにあるすべてのbeginx/endxに適用されます。
ただし、別のスレッドにいるので、使用する必要があります BeginInvoke
メソッドをUIスレッドに派遣します。
コードは次のようになります:
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をUIに送信することもできます。これは、XMLが非常に長い場合はUIを凍結しないようにします(そうではないはずです)。
編集: コードを修正しました。実装するだけです ShowGuildies
. 。インターネットの接続と遅延に関して、操作は別のスレッドで発生するため、UIはフリーズしません。ただし、ロードアニメーションなどを表示することを検討する場合があります。