1. 程式人生 > >Lind.DDD.Utils.HttpHelper關於對HttpClient的正確使用

Lind.DDD.Utils.HttpHelper關於對HttpClient的正確使用

回到目錄

官方的不一定是對的,機器最能證明一切

不知道從什麼時候起,我們在寫資料庫連線,網路連線,檔案操作時會習慣加上using,這種習慣被我們誤稱為一種模式,但事實上,一切事情都有因有果的,使用using的作用是什麼?我想這個問題大家都知道應該,它可以釋放資源,而對於資料庫連線來說,它不是釋放資料連線,而只是把連線放裡“連線池”,等待下次使用時,直接用池子裡取出來即可,好處當然就是省去了很多“建立連線”時的開銷,而不對網路連線來說,則不是那麼簡單了,不能一同而義,這點對於MSDN也有錯誤的說法和寫法,最近在看博文時(老外的,Infoq上翻譯的)給出了有利的證據,具體看下文。

using的寫法其實就是對IDispose模組的實現 

  using (var http = new HttpClient(handler))
   {
    http.Timeout = new TimeSpan(0, 0, timeOut);
    HttpResponseMessage response;
    response = http.GetAsync(GeneratorUri(requestUri, ApiValidateHelper.GenerateCipherText(nv))).Result;
    return response;
   }

對於上面的程式碼,也是MSDN推薦的寫法,即在使用完網路資源後,自動釋放它,而對於下一次網路資源的訪問,還需要從新去構建,事實上,從資源的銷燬到下次資源的建立需要很大的代價,而且你的網路連線的構建(套接字)是有限制的,並不是無窮無近的,所以,我們必須要進行控制。

下面是大叔對using方式進行的測試,可以通過截圖看到,我們的TCP連線有很多,這樣當高併發情況下,你的套接字連線將會被用斤。

可用套接字耗盡後可能出現這樣的異常:System.Net.Sockets.SocketException!

改進後的程式(單例或者靜態化的HttpClient)

   readonly static HttpClient http = new HttpClient(new HttpClientHandler()
        {
            AutomaticDecompression = System.Net.DecompressionMethods.GZip
        });
        [TestMethod]
        
public void Get() { Stopwatch sw = new Stopwatch(); sw.Restart(); for (int i = 0; i < 1000; i++) { var response = http.GetAsync("http://www.sina.com").Result; } sw.Stop(); Console.WriteLine("1000個請求的時間" + sw.ElapsedMilliseconds); }

修改之後,我們可以看到整個HttpClient的測試效能有了明顯的提升!

對於控制檯輸出的TCP連線情況,我們也只看到一條相關的資料,這也是我們希望看到的!

netstat -nbp | findstr 202.108.33.107

結果

最後,感謝Infoq的編輯“謝麗”找了這麼好的一篇文章,辛苦了!

回到目錄