新物网

当前位置:首页 > 百科

百科

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

时间:2023-10-17 20:44:08 雅雅
    想在很多个月前做的软件中添加一个天气预报功能, 也就是说,使用Google Weather接口: http://www.google.com/ig/api?hl=z

    想在很多个月前做的软件中添加一个天气预报功能, 也就是说,使用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来搜索gogle.com对应于特定的IP地址, 这项任务需要很长时间.

        事实上,我Pinggggoogle.com之后, google.用IP地址代替com, 运作程序, 没有发现它不起作用...

行为2: 程序只完成Begingetresponse的多线程, 还有GetResponseStream等等,没有多线程。.

        但将Getresponsestream改为Begingetresponsestream后, 没有变化。

行为3: 设备按需分配给WebRequest, 比如WebRequest, Streamreader是一个“非常大”的对象,需要很长时间.

        想想看,这一定是在计算机内存中进行的, 不需要3秒, 10多秒吧?

        这种情况真的不容易描述, 事实上,经过一系列的测试, 测试发现,只有WebRequest第一次出现,看起来不是多线程. 再试几次传出WebRequest, 得到Response的时间相对较短. 为了找出哪一步比较强, 我写了一个控制面板程序来检测, 我在测试中使用了一个for循环系统, 同一WebRequest持续传出5次, 检测结果如下:

        不难发现,程序在第一次复位WebRequest和第一次从发出请求到获得回应需要更多的时间! 昨天发现其实是代理商。(Proxy)问题! 昨天发现其实是代理商。(Proxy)问题! 关于Httpwebrestttst的MSDN.这样评价Proxy属性:

当地电子计算机或应用程序的环境变量很可能是默认设置代理的特定应用程序。 假如指定了 Proxy 特性,则 Proxy 特征中的网络设置将重写当地电子计算机或应用程序的环境变量, HttpWebRequest 案例将很容易使用指定的网络设置。 如果环境变量中没有指定的代理,也没有找到 Proxy 特性,则 HttpWebRequest 本地计算机中的类别应用程序 Internet Explorer 网络设置中继承。 假如 Internet Explorer 没有网络设置,要求将直接发送到网络服务器。