为什么我不能重用 WebClient 两次发出相同的请求?
Why I can't reuse WebClient to make the same request twice?
所以代码:
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."
如果我处理 WebClient 并重新创建 - 有效,但这会增加额外的性能损失.. 为什么我不能重复使用 WebClient 两次?
WebClient headers 在每次请求后被清除。要亲自查看,您可以添加几个 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!
}
因此,您可以更改代码以每次设置 headers:
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?
这是一个 SO 线程,它似乎不认为每个请求实例化一个 WebClient 会造成很大的性能损失:WebClient construction overhead
祝你好运!
这可能不是您要找的,但这就是我解决这个问题的方法。
public WebClient WebClient
=> new WebClient {Headers = new WebHeaderCollection {{HttpRequestHeader.ContentType, "application/json"}}};
这会在您每次使用时创建一个新的 WebClient。我这样做可能效率不高,但对于我使用它的原因来说,它运行良好并且无需考虑为每个请求设置 headers。
所以代码:
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."
如果我处理 WebClient 并重新创建 - 有效,但这会增加额外的性能损失.. 为什么我不能重复使用 WebClient 两次?
WebClient headers 在每次请求后被清除。要亲自查看,您可以添加几个 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!
}
因此,您可以更改代码以每次设置 headers:
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?
这是一个 SO 线程,它似乎不认为每个请求实例化一个 WebClient 会造成很大的性能损失:WebClient construction overhead
祝你好运!
这可能不是您要找的,但这就是我解决这个问题的方法。
public WebClient WebClient
=> new WebClient {Headers = new WebHeaderCollection {{HttpRequestHeader.ContentType, "application/json"}}};
这会在您每次使用时创建一个新的 WebClient。我这样做可能效率不高,但对于我使用它的原因来说,它运行良好并且无需考虑为每个请求设置 headers。