0

我整个周末都被困在这上面,惨遭失败!
请帮助我恢复理智!!

你的挑战

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

看看这个链接并打开源代码。你会明白我的意思: http ://eu.wowarmory.com/guild-info.xml?r=Eonar&n=Gifted and 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 armoury 返回 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 是的,我注意到公会名义中的讽刺意味:)

4

1 回答 1

1

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

其次,BeginGetResponse是一个异步操作,所以当它完成时,它会在另一个线程上调用一个回调函数,here 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 不会冻结。您可能会考虑显示加载动画或其他内容。

于 2010-05-23T20:24:25.810 回答