西西软件园多重安全检测下载网站、值得信赖的软件下载站!
软件
软件
文章
搜索

首页编程开发其它知识 → 解决一个“异步方法却假死”的问题

解决一个“异步方法却假死”的问题

相关软件相关文章发表评论 来源:西西整理时间:2011/4/4 22:46:18字体大小:A-A+

作者:佚名点击:78次评论:0次标签: 异步

  • 类型:行业软件大小:1.5M语言:中文 评分:5.0
  • 标签:
立即下载

    几个月前做的一个软件里想添加一个天气预报功能, 也就是利用了一下Google Weather的接口: http://www.google.com/ig/api?hl=zh-cn&weather=某某市,某某省 , 效果也达到了.

        不忘书中所讲: 耗时操作, 且非计算密集型任务, 最好使用异步方法. 根据Anders Hejlsberg的视频中演示的那样, 我写出下面一段代码, 也是很多人拿来演示异步的经典写法:

00
public void GetWeather(string city, string province)

01
{

02
var myRequest = (HttpWebRequest)WebRequest.Create("http://www.google.com/ig/api?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), 一边看着我的代码, 我不是异步了么? 异步不是就是为了避免程序假死的么? 目前来看程序似乎并没有异步.

        于是开始找原因...也请教了不少人...也得到了一些可能的原因:

嫌疑1: 程序运行的时候第一步在寻找DNS将google.com对应到某个具体的IP地址, 这项任务花费了不少时间.

        事实上我Ping了google.com之后, 把google.com换成IP地址, 运行程序, 并没有发现有什么效果...

嫌疑2: 程序只实现了BeginGetResponse的异步, 还有GetResponseStream等等之类的方法并没有异步.

        但把GetResponseStream改成BeginGetResponseStream之后, 也没有任何改观.

嫌疑3: 系统在给这个WebRequest分配资源, 诸如WebRequest类, StreamReader之类的还算"比较大"的对象花费了时间.

        想一想这些应该都是在高速缓存上进行的, 不至于要花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;

    相关评论

    阅读本文后您有什么感想? 已有人给出评价!

    • 8 喜欢喜欢
    • 3 顶
    • 1 难过难过
    • 5 囧
    • 3 围观围观
    • 2 无聊无聊

    热门评论

    最新评论

    发表评论 查看所有评论(0)

    昵称:
    表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲
    字数: 0/500 (您的评论需要经过审核才能显示)