2016-02-29 58 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。我这样做对你来说效率可能不高,但是对于我使用它的原因,它效果很好,并且不需要考虑为每个请求设置标题。

相关问题