天天看點

關于微軟HttpClient使用,避免踩坑

最近公司對于WebApi的場景使用也越來越加大了,随之而來就是Api的用戶端工具我們使用哪個?我們最常用的估計就是HttpClient,在微軟類庫中命名空間位址:System.Net.Http,是一個支援異步程式設計的API的SDK架構;我在公司開發項目時,查閱了一些資料對這個Client如何使用的更合理,最大的保障就是承受高頻繁的用戶端發起連接配接和線程安全,接下來我就簡要說說如何合理使用。

一、普通場景使用(算是坑了)

先看一下代碼: 

1             while (true)
2             {
3                 using (HttpClient client = new HttpClient())
4                 {
5                     var result = client.GetStringAsync("http://www.xxxxx.com").Result;
6                     Console.WriteLine($"{result} > {DateTime.Now}");
7                 }
8             }      

以上代碼請求必定在持續一段時間内會報錯【大家在測試url位址時希望是内部區域網路絡】;

有人會說這個是單線程估計沒意思,我想說的是,如果你多線程裡用using可能測試出來沒問題,但想想線程的開啟對CPU來說是一筆不小的開銷,所有真正壓倒api通路的頻率其實不是特别高頻率了;

二、優化場景使用

1             HttpClient client = new HttpClient();//這裡的client可以用單例模式進行預先初始化
2             while (true)
3             {
4                 var result = client.GetStringAsync("http://www.xxxx.com/").Result;
5                 Console.WriteLine($"{result} > {DateTime.Now}");
6             }      

而且由于裡面的異步方法是線程安全的,是以不用擔心多線程使用問題!

2017.1.5

注意了DeleteAsync在高并發情況會出現問題,大家謹慎使用

三、關于DNS的BUG

我覺得這個問題,不是不可以解決,如果用Nginx我覺得就能暫時解決這個換IP遷移等問題;

在InfoQ上的對HttpClient的缺陷文章:http://www.infoq.com/cn/news/2016/09/HttpClient

題外話:關于最佳單例模式的寫法

private static HttpClient client;
        public static HttpClient Singleton
        {
            get
            {
                if (client == null)
                {
                    Interlocked.CompareExchange(ref client,new HttpClient(),null);
                }
                return client;
            }
        }      

後續:近期我們公司技術同僚對using和單例模式,進行不同的壓測,最後得出結論是HttpClient在同步模式下使用生産環境是相對性能沒有異步好,故項目有必要進行.NET FRAMEWORK提升到4.5以上,這樣會有更好性能 > 2017.1.11