Windows Phone 中 WebClient,HttpWebRequest,UI Thread 浅析 - [WP开发]

之前的一篇随笔里总结过WebClient的用法与HttpWebRequest的区别,这里也有对两者的分析,本文总结的主要是针对Windows Phone网络编程时它们之间的联系与用法,也是为写腾讯微博Windows Phone版本的SDK做准备。首先简单的回顾下各自的用法,最后用一个小实例来加深理解。

  • WebClient

WebClient提供向 URI 标识的资源发送数据和从 URI 标识的资源接收数据的公共方法。
WebClient 类提供向 URI(支持以 http:、https:、ftp:、和 file: 方案标识符开头的 URI) 标识的任何本地、Intranet 或 Internet 资源发送数据以及从这些资源接收数据的公共方法。WebClient 类使用 WebRequest 类提供对资源的访问。
WebClient 实例可以通过任何已向 WebRequest.RegisterPrefix 方法注册的 WebRequest 子代访问数据。

可以在MSDN上查看WebClient类的方法,属性及事件。

 

  • HttpWebRequest

提供 WebRequest 类的 HTTP 特定的实现。 HttpWebRequest 对 HTTP 协议进行了完整的封装,程序使用 HTTP 协议和服务器交互主要是进行数据的提交,通常数据的提交是通过 GET 和 POST 两种方式来完成。
需要注意的是: HttpWebRequest使用基于代理的异步编程模型,在HTTP响应返回时引发的HttpWebRequest回调不是在UI线程上返回的,因此在该回调中需要额外代码处理UI,否则就会产生"跨线程访问无效"错误。

同样可以在MSDN上查看HttpWebRequest类的方法,属性及事件。

 

  • UI Thread

Silverlight for Desktop中没有单独的render thread,跟界面相关的操作都运行在一个UI thread中。而在Windows Phone中,有两个线程,一个是UI Thread,一个是Render Thread。首先解释下SL4desktop中为什么没有没有Render thread,Michail是这样解释的:

"The decision came down to a tradeoff between system overhead and decoupling framerates . With Silverlight, we went with a lighter weight on-thread approach and did not isolate your application code from the rendering system. That means you can do more in your animation (like have layout-based animation or custom code running) and there is minimal latency and overhead getting to the rendering system. The down side is if you do too much, you can interfere with operations such as video playback.
That said, the Silverlight rendering system will take advantage of multi-core processing and use many threads to speed up rendering for it. So, rendering is rarely "on thread," (感觉是笔误,应为 "one thread") but it is synchronized with your app to avoid synchronization plus copies of data."

在Windows Phone中,分成了两个线程,有兴趣的同学可以看下channel9.msdn.com上的一个"Sliverlight Performance on Windows Phone"主题的视频。里面的演示提及到设计的原则(ps.channel9上有不少好教程,顺便练下听力也是件好事)。

The UI thread handles touch input, layout, and the CompositionTarget.Rendering event. Some worker threads are also used for jobs such as rasterization, media decoding, sensors, and asynchronous web access. 所以在Windows Phone的网络编程中特别要注意异步操作时对UI线程的影响。

 

  • Windows Phone网络编程中需要注意的问题

这小节是本文的重点,只要总结下自己遇到的问题,很欢迎大家补充。在使用HttpWebRequest这个类时,要记得的是only the asynchronous methods are available,所以GetResponse这个方法就不适用啦,需要通过异步的方式去实现,例如MSDN论坛上的一个例子,大家看下那个例子就知道应该怎样去处理。

 

  • Demo

 新建WP工程WebRequestDemo,增加两个Textblock,分别通过WebClient与HttpWebRequest两种方式去异步请求网络资源,并且在回调函数中更新UI。Code-Behide代码如下:

namespace WebRequestDemo
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }
        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            DoWebClient();
            DoHttpWebRequest();
        }

        private void DoWebClient()
        {
            var webClient = new WebClient();
            webClient.OpenReadAsync(new Uri("http://wwww.baidu.com"));
            webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);

        }

        void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            using (var reader = new StreamReader(e.Result))
            {
                webClientTextBlock.Text = reader.ReadToEnd();
            }
        }

        private void DoHttpWebRequest()
        {
            string url = "http://www.baidu.com";

            var request = HttpWebRequest.Create(url);
            var result = (IAsyncResult)request.BeginGetResponse(ResponseCallback, request);
        }

        private void ResponseCallback(IAsyncResult result)
        {
            var request = (HttpWebRequest)result.AsyncState;
            var response = request.EndGetResponse(result);

            using (var stream = response.GetResponseStream())
            using (var reader = new StreamReader(stream))
            {
                var contents = reader.ReadToEnd();
                Dispatcher.BeginInvoke(() => { httpWebRequestTextBlock.Text = contents; });//特别注意需要通过Dispatcher去更新UI进程
            }
        }

    }
}

 

 

posted @ 2011-10-08 15:54  卿之  阅读(3078)  评论(8编辑  收藏  举报
无觅相关文章插件,快速提升流量