使用 C# 异步 Silverlight 4 调用魔兽世界军械库流式 XML

发布于 2024-09-02 14:26:41 字数 2571 浏览 5 评论 0原文

我整个周末都被困在这个问题上并且惨败!
请帮我找回理智!!

您的挑战

对于我的第一个 Silverlight 应用程序,我认为使用《魔兽世界》军械库列出我的公会中的角色会很有趣。这涉及到从 Silverlight(废话!)到基于 XML 的 WoW 军械库的异步。简单呃?

查看此链接并打开源代码。你就会明白我的意思: http://eu.wowarmory.com/guild-info。 xml?r=Eonar&n=Gifted 和 Talented

下面是获取 XML 的代码(对 ShowGuildies 的调用将处理返回的 XML - 我已经在本地测试过它,我知道它有效)。

我根本没有获得预期的返回 XML。

注释

  • 如果浏览器能够转换 XML,它将执行此操作,否则将提供 HTML。我认为它检查了 UserAgent
  • 我是一位经验丰富的 asp.net Web 开发人员 C#,所以如果您开始谈论 Windows 窗体/WPF 本机,请轻松一点
  • 我似乎无法在 .net 4.0 中设置 UserAgent 设置 - 似乎不能由于某种原因成为 HttpWebRequest 对象的一个​​属性 - 我认为它曾经是可用的。
  • Silverlight 4.0(在我将 Silverlight 安装更新到 4.0 之前最初创建为 3.0)
  • 使用 C# 4.0 创建
  • 请解释一下,就好像您与 Web 开发人员交谈而不是正确的编程哈哈!

下面是代码 - 它应该从 wow 军械库返回 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?
            }

真的希望有人能帮助我!

谢谢多谢! 担。

PS 是的,我注意到公会名称中的讽刺:)

I have been stuck on this all weekend and failed miserably!
Please help me to claw back my sanity!!

Your challenge

For my first Silverlight application I thought it would be fun to use the World of Warcraft armoury to list the characters in my guild. This involves making an asyncronous from Silverlight (duh!) to the WoW armoury which is XML based. SIMPLE EH?

Take a look at this link and open the source. You'll see what I mean:
http://eu.wowarmory.com/guild-info.xml?r=Eonar&n=Gifted and Talented

Below is code for getting the XML (the call to ShowGuildies will cope with the returned XML - I have tested this locally and I know it works).

I have not managed to get the expected returned XML at all.

Notes:

  • If the browser is capable of transforming the XML it will do so, otherwise HTML will be provided. I think it examines the UserAgent
  • I am a seasoned asp.net web developer C# so go easy if you start talking about native to Windows Forms / WPF
  • I can't seem to set the UserAgent setting in .net 4.0 - doesn't seem to be a property off the HttpWebRequest object for some reason - i think it used to be available.
  • Silverlight 4.0 (created as 3.0 originally before I updated my installation of Silverlight to 4.0)
  • Created using C# 4.0
  • Please explain as if you talking to a web developer and not a proper programming lol!

Below is the code - it should return the XML from the wow armoury.

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

Really hope someone out there can help me!

Thanks mucho!
Dan.

PS Yes, I have noticed the irony in the name of the guild :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

九命猫 2024-09-09 14:26:41

首先,仅当您位于 UI 线程之外的另一个线程(发生与 silverlight/WPF 相关的所有事情的地方)时,才需要 Dispatcher.BeginInvoke。在单击事件中,您已经处于 UI 线程中,因此无需调用它。

其次,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 不会冻结。您可能会考虑显示加载动画或其他内容。

First, Dispatcher.BeginInvoke is only needed when you're on another thread than the UI thread (where everything silverlight/WPF related happens). On a click event, you're already in the UI thread so there's no need to call it.

Second, BeginGetResponse is an asynchronous operation so when it has finished, it will call a callback function on another thread, here ReqCallback. It's in this method that you can call EndGetResponse. This pattern applies to every BeginX/EndX you'll find in the framework.

However, since you're in another thread, you'll need to use BeginInvoke to dispatch a method back to the UI thread.

The code will look like this:

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)));
    }
}

Note that you can also process the XML in the thread and use the dispatcher only to send back guildies to the UI, to avoid freezing the UI if the XML is very long to parse (shouldn't be the case).

Edit: Corrected the code. You only have to implement ShowGuildies. Regarding the internet connectivity and delays, since the operation occurs in another thread the UI won't freeze. You might consider showing a loading animation or something though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文