2016-02-29 101 views
2

因此,代碼:爲什麼我不能重複使用WebClient來做同樣的請求兩次?

 const long testCount = 2; 
     const string jsonInput = "{\"blockId\":\"1\",\"userId\":\"{7c596b41-0dc3-45df-9b4c-08840f1da780}\",\"sessionId\":\"{46cd1b39-5d0a-440a-9650-ae4297b7e2e9}\"}"; 

     Stopwatch watch = Stopwatch.StartNew(); 

     using (var client = new WebClient()) 
     { 
      client.Headers["Content-type"] = "application/json"; 
      client.Encoding = Encoding.UTF8; 

      for (int i = 0; i < testCount; i++) 
      { 
       var response = client.UploadString("http://localhost:8080/BlocksOptimizationServices/dataPositions", "POST", jsonInput); 
      } 

      watch.Stop(); 
      double speed = watch.ElapsedMilliseconds/(double)testCount; 
      Console.WriteLine("Avg speed: {0} request/ms", testCount); 

測試性能時,我只是想打電話給client.UploadString("http://localhost:8080/BlocksOptimizationServices/dataPositions", "POST", jsonInput)多次。但經過它總是第一個請求失敗,

"The remote server returned an error: (400) Bad Request."

如果我處理Web客戶端和重建 - 作品,但這種增加額外的性能損失。爲什麼我不能重複使用的WebClient兩次?

+4

你是否在運行Fiddler時運行過兩次並比較了請求?後續請求顯然會到達服務器以接收400錯誤。 –

回答

6

WebClient標頭在每次請求後被清除。要親自看看,可以添加一對Debug.Assert()語句。這是你的「(400)錯誤的請求」在第二請求錯誤是一致的:

for (int i = 0; i < testCount; i++) 
{ 
     Debug.Assert(client.Headers.Count == 1); // Content-type is set 
     var response = client.UploadString("http://localhost:8080/BlocksOptimizationServices/dataPositions", "POST", jsonInput);  
     Debug.Assert(client.Headers.Count == 0); // Zero! 
} 

所以,你可以改變你的代碼設置頁眉每次:

using (var client = new WebClient()) 
{    
    for (int i = 0; i < testCount; i++) 
    { 
     client.Headers["Content-type"] = "application/json"; 
     client.Encoding = Encoding.UTF8; 

     var response = client.UploadString("http://localhost:8080/BlocksOptimizationServices/dataPositions", "POST", jsonInput); 
    } 

If I dispose WebClient and recreate - works, but this add extra performance penalty.. why I can't reuse WebClient twice?

這裏的一個似乎沒有想到每個請求實例化一個WebClient的SO線程是一個性能損失:WebClient construction overhead

祝你好運!

0

這可能不是你要找的東西,但這是我如何解決這個問題的。

public WebClient WebClient 
       => new WebClient {Headers = new WebHeaderCollection {{HttpRequestHeader.ContentType, "application/json"}}}; 

這會在您每次使用它時創建一個新的WebClient。我這樣做對你來說效率可能不高,但是對於我使用它的原因,它效果很好,並且不需要考慮爲每個請求設置標題。

相關問題