西西軟件園多重安全檢測(cè)下載網(wǎng)站、值得信賴的軟件下載站!
軟件
軟件
文章
搜索

首頁(yè)編程開(kāi)發(fā)其它知識(shí) → 解決一個(gè)“異步方法卻假死”的問(wèn)題

解決一個(gè)“異步方法卻假死”的問(wèn)題

相關(guān)軟件相關(guān)文章發(fā)表評(píng)論 來(lái)源:西西整理時(shí)間:2011/4/4 22:46:18字體大。A-A+

作者:佚名點(diǎn)擊:78次評(píng)論:0次標(biāo)簽: 異步

三相異步電機(jī)圖形編輯器v2.0 綠色免費(fèi)版
  • 類(lèi)型:行業(yè)軟件大。1.5M語(yǔ)言:中文 評(píng)分:5.0
  • 標(biāo)簽:
立即下載

    幾個(gè)月前做的一個(gè)軟件里想添加一個(gè)天氣預(yù)報(bào)功能, 也就是利用了一下Google Weather的接口: http://www.google.com/ig/api?hl=zh-cn&weather=某某市,某某省 , 效果也達(dá)到了.

        不忘書(shū)中所講: 耗時(shí)操作, 且非計(jì)算密集型任務(wù), 最好使用異步方法. 根據(jù)Anders Hejlsberg的視頻中演示的那樣, 我寫(xiě)出下面一段代碼, 也是很多人拿來(lái)演示異步的經(jīng)典寫(xiě)法:

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
}

        就是這樣的一個(gè)所謂異步的方法, 運(yùn)行一下, 最短的時(shí)候花了3秒多才獲取到了weatherString, 很多時(shí)候甚至花了10秒多. 我就眼巴巴的看著程序在假死(Not Responding), 一邊看著我的代碼, 我不是異步了么? 異步不是就是為了避免程序假死的么? 目前來(lái)看程序似乎并沒(méi)有異步.

        于是開(kāi)始找原因...也請(qǐng)教了不少人...也得到了一些可能的原因:

嫌疑1: 程序運(yùn)行的時(shí)候第一步在尋找DNS將google.com對(duì)應(yīng)到某個(gè)具體的IP地址, 這項(xiàng)任務(wù)花費(fèi)了不少時(shí)間.

        事實(shí)上我Ping了google.com之后, 把google.com換成IP地址, 運(yùn)行程序, 并沒(méi)有發(fā)現(xiàn)有什么效果...

嫌疑2: 程序只實(shí)現(xiàn)了BeginGetResponse的異步, 還有GetResponseStream等等之類(lèi)的方法并沒(méi)有異步.

        但把GetResponseStream改成BeginGetResponseStream之后, 也沒(méi)有任何改觀.

嫌疑3: 系統(tǒng)在給這個(gè)WebRequest分配資源, 諸如WebRequest類(lèi), StreamReader之類(lèi)的還算"比較大"的對(duì)象花費(fèi)了時(shí)間.

        想一想這些應(yīng)該都是在高速緩存上進(jìn)行的, 不至于要花3秒, 10多秒吧?

        這個(gè)問(wèn)題還真不太好描述, 事實(shí)上后來(lái)做了一系列的測(cè)試, 測(cè)試發(fā)現(xiàn)只有第一次發(fā)出WebRequest看似不是異步的. 接下來(lái)繼續(xù)嘗試幾次發(fā)出WebRequest, 到獲得Response的時(shí)間就非常非常短. 為了找出究竟在哪個(gè)環(huán)節(jié)耗時(shí)比較厲害, 我寫(xiě)了一個(gè)控制臺(tái)程序來(lái)測(cè)試, 測(cè)試中我用了一個(gè)for循環(huán), 連續(xù)發(fā)出5次同樣的WebRequest, 測(cè)試結(jié)果如下:

        可以發(fā)現(xiàn)程序在第一次初始化WebRequest和第一次從發(fā)出請(qǐng)求到獲得響應(yīng)消耗的時(shí)間最多! 昨天發(fā)現(xiàn)原來(lái)是代理(Proxy)的問(wèn)題! MSDN中關(guān)于HttpWebRequest.Proxy屬性是這樣描述的:

本地計(jì)算機(jī)或應(yīng)用程序配置文件可能指定使用默認(rèn)代理。 如果指定了 Proxy 屬性,則 Proxy 屬性中的代理設(shè)置會(huì)重寫(xiě)本地計(jì)算機(jī)或應(yīng)用程序配置文件,并且 HttpWebRequest 實(shí)例將實(shí)用指定的代理設(shè)置。 如果配置文件中未指定代理并且未指定 Proxy 屬性,則 HttpWebRequest 類(lèi)使用從本地計(jì)算機(jī)上的 Internet Explorer 中繼承的代理設(shè)置。 如果 Internet Explorer 中沒(méi)有代理設(shè)置,請(qǐng)求會(huì)直接發(fā)送到服務(wù)器。

        回到遇到的問(wèn)題, 程序并沒(méi)有指定代理, 第一次運(yùn)行的時(shí)候, 程序會(huì)尋找IE中的代理, 如果沒(méi)有找到才會(huì)去直接訪問(wèn)服務(wù)器, 這中間花費(fèi)了不少時(shí)間. 要解決這個(gè)問(wèn)題, 請(qǐng)?jiān)诖a中加上這么一行:

xxRequest.Proxy = null;

    相關(guān)評(píng)論

    閱讀本文后您有什么感想? 已有人給出評(píng)價(jià)!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過(guò)難過(guò)
    • 5 囧
    • 3 圍觀圍觀
    • 2 無(wú)聊無(wú)聊

    熱門(mén)評(píng)論

    最新評(píng)論

    發(fā)表評(píng)論 查看所有評(píng)論(0)

    昵稱:
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過(guò)審核才能顯示)