HttpWebRequest 二三事


隨着REST風格的流行,直接通過 HttpWebRequest 進行服務調用的客戶端應用越來越多。這里總結一些可能需要費時調查的經驗,希望能幫助大家。

1. 用完的HttpWebRequest要Abort()或者要把 Response.Close()
否則會導致請求Timeout。 (HttpWebRequest.Method默認是GET)

 

[c-sharp] view plain copy print ?
 
  1. static   void  Main( string [] args)  
  2. {  
  3. for  ( int  i = 0; i < 10; i++)  
  4.     {  
  5.         Console.Write( "[{0}] Request - " , i + 1);  
  6.         TryGet( "https://login.live.com/" );  
  7.     }  
  8.     Console.Read();  
  9. }  
  10. static   void  TryGet( object  obj)  
  11. {  
  12. try   
  13.     {  
  14.         HttpWebRequest webReq =  null ;  
  15. string  url = ( string )obj;  
  16.         webReq = (HttpWebRequest)HttpWebRequest.Create(url);  
  17.         webReq.Timeout = 20 * 1000;  
  18.         var resp = webReq.GetResponse()  as  HttpWebResponse;  
  19.         resp.Close();  
  20.         Console.WriteLine( "Get Response StatusCode: {0}({1})" ,   
  21.             resp.StatusCode, ( int )resp.StatusCode);  
  22.     }  
  23. catch  (WebException we)  
  24.     {  
  25.         Console.WriteLine( "Get Response StatusCode: {0}({1})" ,  
  26.             we.Status, ( int )we.Status);  
  27.     }  
  28. catch  (Exception ex)  
  29.     {  
  30.         Console.WriteLine(ex);  
  31.     }  
  32. }  


上面的代碼,會從第3次Request開始出現Timeout,因為GetResponse 后 Stream打開未關閉。

解決方法:上面的代碼中加上 resp.Close(); 或者 webReq.Abort(); 就能解決。

2. 多線程中調用 HttpWebRequest 時,需要設置 ServicePointManager.DefaultConnectionLimit 數(默認連接數是 2)。
當多線程請求時,同時的連接數超過Limit時,GetResponse會拋出 Timeout WebException。

[c-sharp] view plain copy print ?
 
  1. // 用多線程同時發出4個請求   
  2. WaitCallback methodTarget =  new  WaitCallback(TryGet);  
  3. ThreadPool.QueueUserWorkItem(methodTarget,  "https://login.live.com/" );  
  4. ThreadPool.QueueUserWorkItem(methodTarget,  "https://login.live.com/" );  
  5. ThreadPool.QueueUserWorkItem(methodTarget,  "https://login.live.com/" );  
  6. ThreadPool.QueueUserWorkItem(methodTarget,  "https://login.live.com/" );  

解決方法:在GetResponse()之前設置 ServicePointManager.DefaultConnectionLimit = 100;

3.  當請求一個基於SSL的服務時,默認的驗證行為都在 ServicePointManager 定義:
ServicePointManager.CheckCertificateRevocationList = true;

如果請求的服務端證書沒有第三方的認證支持,則請求會失敗,如果要完全信任服務端證書,則可以將
CheckCertificateRevocationList  設為 false。

4. 可以在 <system.net> 配置節中配置 HttpWebRequest 的屬性,包括 WebProxy

[c-sharp] view plain copy print ?
 
  1. <system.net>    
  2.   <connectionManagement>    
  3.   </connectionManagement>   
  4.   <defaultProxy>    
  5.     <proxy proxyaddress= "http://xxx.xxx.xxx.xxx:xxx"  bypassonlocal= "False" />    
  6.   </defaultProxy>   
  7.   <settings>    
  8.       <httpWebRequest useUnsafeHeaderParsing= "true" />   
  9.       <servicePointManager checkCertificateName= "true"      
  10.                            checkCertificateRevocationList= "true"       
  11.                            enableDnsRoundRobin= "true"      
  12.                            expect100Continue= "true"        
  13.                            useNagleAlgorithm= "true" />      
  14.   </settings>   
  15. </system.net>  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM