刮取Windows手机应用程序的网页源代码

时间:2012-01-22 22:53:17

标签: c# windows-phone-7 asynchronous event-handling webclient

我非常擅长使用C#开发WP7。我正在尝试编写一个简单的应用程序,它将从textBox1获取url并在按下button1时使用该页面的源代码更新textBlock1中的Text。

我坚持的部分是如何将DownloadStringCallback2中的Result传递回LoadSiteContent函数,以便它可以作为变量sourceCode返回。

代码如下:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;

namespace TestApp1
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            string url = textBox1.Text;
            string sourceCode = LoadSiteContent(url);
            textBlock1.Text = sourceCode;
        }

        /// <summary>
        /// method for retrieving information from a specified URL
        /// </summary>
        /// <param name="url">url to retrieve data from</param>
        /// <returns>source code of URL</returns>
        public string LoadSiteContent(string url)
        {
            //create a new WebClient object
            WebClient client = new WebClient();

            //create a byte array for holding the returned data
            string sourceCode = "Fail";
            client.DownloadStringCompleted += new    DownloadStringCompletedEventHandler(DownloadStringCallback2);
           client.DownloadStringAsync(new Uri(url));

           //use the UTF8Encoding object to convert the byte
           //array into a string
           //UTF8Encoding utf = new UTF8Encoding();

           //return the converted string
           //return utf.GetString(html, 0, html.Length);
           return sourceCode;
        }

        private static void DownloadStringCallback2(Object sender, DownloadStringCompletedEventArgs e)
        {
           // If the request was not canceled and did not throw
           // an exception, display the resource.
           if (!e.Cancelled && e.Error == null)
           {
               string textString = (string)e.Result;
           } 
        }
    }
}

1 个答案:

答案 0 :(得分:2)

你不能像你想要的那样去做,因为WP7(silverlight)中的web请求是异步的。 这意味着代码在下载网页时不会停止,并且在完成相同的行和功能时继续执行,而是创建新的线程,下载文件并调用回调函数。

您必须继续使用回调函数(在您的情况下为DownloadStringCallback2)。 在该函数中,您必须将源代码(e.Result)放入文本框中。

如果您遇到跨线程异常,或者如果您希望在执行任务时保持UI的正常使用,我可以添加它,您可以使用此命令:

Dispatcher.BeginInvoke(new Action (() => LoadContent("http://www.google.com")));

此命令修复了跨线程异常(如果我没记错的话)并在与UI线程不同的线程上执行代码,从而保持稳定的UI。

编辑我认为您的代码应如下所示:

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        string url = textBox1.Text;
        LoadSiteContent(url);
    }

    public string LoadSiteContent(string url)
    {
        //create a new WebClient object
        WebClient client = new WebClient();

        client.DownloadStringCompleted += new    DownloadStringCompletedEventHandler(DownloadStringCallback2);
       client.DownloadStringAsync(new Uri(url));
    }

    private static void DownloadStringCallback2(Object sender, DownloadStringCompletedEventArgs e)
    {
       // If the request was not canceled and did not throw
       // an exception, display the resource.
       if (!e.Cancelled && e.Error == null)
       {
           textBlock1.Text = (string)e.Result;
           //If you get the cross-thread exception then use the following line instead of the above
           //Dispatcher.BeginInvoke(new Action (() => textBlock1.Text = (string)e.Result));
       } 
    }