本文选之一个人博客,很实用的经验之谈,建站学为你奉献,希望实际应用中对你有帮助。
几个月前做的一个软件里想添加一个天气预报功能, 也就是利用了一下Google Weather的接口: ?hl=zh-cn&weather=某某市,某某省 , 效果也达到了.
不忘书中所讲: 耗时操作, 且非计算密集型任务, 最好使用异步方法. 根据Anders Hejlsberg的视频中演示的那样, 我写出下面一段代码, 也是很多人拿来演示异步的经典写法:
00 public void GetWeather(string city, string province)
01 {
02 var myRequest = (HttpWebRequest)WebRequest.Create("?hl=zh-cn&weather=" + city + "," + province);
03 myRequest.BeginGetResponse(delegate(IAsyncResult ar)
04 {
05 var response = myRequest.EndGetResponse(ar);
06 StreamReader weatherStream = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("gb2312"));
07 string weatherString = weatherStream.ReadToEnd();
08 weatherStream.Dispose();
09 }, null);
10 }
就是这样的一个所谓异步的方法, 运行一下, 最短的时候花了3秒多才获取到了weatherString, 很多时候甚至花了10秒多. 我就眼巴巴的看着程序在假死(Not Responding), 一边看着我的代码, 我不是异步了么? 异步不是就是为了避免程序假死的么? 目前来看程序似乎并没有异步.
于是开始找原因...也请教了不少人...也得到了一些可能的原因:
事实上我Ping了google.com之后, 把google.com换成IP地址, 运行程序, 并没有发现有什么效果...
但把GetResponseStream改成BeginGetResponseStream之后, 也没有任何改观.
想一想这些应该都是在高速缓存上进行的, 不至于要花3秒, 10多秒吧?
这个问题还真不太好描述, 事实上后来做了一系列的测试, 测试发现只有第一次发出WebRequest看似不是异步的. 接下来继续尝试几次发出WebRequest, 到获得Response的时间就非常非常短. 为了找出究竟在哪个环节耗时比较厉害, 我写了一个控制台程序来测试, 测试中我用了一个for循环, 连续发出5次同样的WebRequest, 测试结果如下:
可以发现程序在第一次初始化WebRequest和第一次从发出请求到获得响应消耗的时间最多! 昨天发现原来是代理(Proxy)的问题! MSDN中关于HttpWebRequest.Proxy属性是这样描述的:
本地计算机或应用程序配置文件可能指定使用默认代理。 如果指定了 Proxy 属性,则 Proxy 属性中的代理设置会重写本地计算机或应用程序配置文件,并且 HttpWebRequest 实例将实用指定的代理设置。 如果配置文件中未指定代理并且未指定 Proxy 属性,则 HttpWebRequest 类使用从本地计算机上的 Internet Explorer 中继承的代理设置。 如果 Internet Explorer 中没有代理设置,请求会直接发送到服务器。
回到遇到的问题, 程序并没有指定代理, 第一次运行的时候, 程序会寻找IE中的代理, 如果没有找到才会去直接访问服务器, 这中间花费了不少时间. 要解决这个问题, 请在代码中加上这么一行:
xxRequest.Proxy = null;