HttpClient.GetAsync一次只执行2个请求?
HttpClient.GetAsync executes only 2 requests at a time?
为什么 HttpClient.GetAsync()/PostAsync()/SendAsync() 等一次只能调度 2 个请求?
我通过以下方式对此进行了测试:
我有一个异步 GET 方法,它在响应之前等待 10 秒而不阻塞。
public async Task<string> Get()
{
var guid = Guid.NewGuid();
System.Diagnostics.Trace.WriteLine($"{guid}: {DateTime.Now.ToLongTimeString()}: start");
await Task.Delay(10000);
System.Diagnostics.Trace.WriteLine($"{guid}: {DateTime.Now.ToLongTimeString()}: end");
return "hello";
}
如果我通过多次刷新从 Chrome 调用端点,我会看到它们在我点击刷新后立即执行,并且我在 10 秒后收到响应:
39a20541-a2d6-4cd0-99cd-db0987e273e9: 5:32:44 PM: start
8326d829-28a6-48a2-9874-6506b79488af: 5:32:44 PM: start
aecfbb10-266c-46f8-be3b-bfc2fadf0775: 5:32:44 PM: start
78932f53-37a5-4f26-a56f-b3196256e1cf: 5:32:44 PM: start
39a20541-a2d6-4cd0-99cd-db0987e273e9: 5:32:54 PM: end
8326d829-28a6-48a2-9874-6506b79488af: 5:32:54 PM: end
aecfbb10-266c-46f8-be3b-bfc2fadf0775: 5:32:54 PM: end
78932f53-37a5-4f26-a56f-b3196256e1cf: 5:32:54 PM: end
但是如果我在控制台应用程序中使用此代码进行调用:
var client = new HttpClient();
for (var ii = 0; ii < 10; ii++)
{
client.GetAsync("http://localhost:50621/api/default");
}
Console.ReadKey();
我看到 Console.ReadKey();
立即到达,但请求是两个两个执行的 - 它发出 2 个请求,然后等待 10 秒完成,然后再 2 个,再等 10 秒,等等,甚至虽然据说所有 10 个都已安排。
80546610-c20e-4ff1-b6e5-0fe1688e8803: 5:39:10 PM: start
9bbbb707-9ea7-44da-9d5b-03efc3c4aa47: 5:39:10 PM: start
80546610-c20e-4ff1-b6e5-0fe1688e8803: 5:39:20 PM: end
9bbbb707-9ea7-44da-9d5b-03efc3c4aa47: 5:39:20 PM: end
a146c3ca-a0d2-4588-b60b-156f1febc944: 5:39:20 PM: start
b71bc77f-9bdb-4aa6-936e-c702eb7d49eb: 5:39:20 PM: start
....
那么为什么不立即提出所有请求? HttpClient 是否对未决请求有某种限制?
HttpClient
,以及其他与http相关的类,使用服务点进行http连接管理:
The ServicePoint class handles connections to an Internet resource
based on the host information passed in the resource's Uniform
Resource Identifier (URI). The initial connection to the resource
determines the information that the ServicePoint object maintains,
which is then shared by all subsequent requests to that resource.
有ServicePointManager.DefaultConnectionLimit
static 属性,它控制着ServicePoint
对象默认允许的最大并发连接数,默认情况下这个属性的值为2。
这意味着默认情况下您只能与给定主机建立 2 个并发连接。要 "fix" 这个 - 将该数字增加到某个更大的值,通常在应用程序启动时的某个位置。
为什么 HttpClient.GetAsync()/PostAsync()/SendAsync() 等一次只能调度 2 个请求?
我通过以下方式对此进行了测试:
我有一个异步 GET 方法,它在响应之前等待 10 秒而不阻塞。
public async Task<string> Get()
{
var guid = Guid.NewGuid();
System.Diagnostics.Trace.WriteLine($"{guid}: {DateTime.Now.ToLongTimeString()}: start");
await Task.Delay(10000);
System.Diagnostics.Trace.WriteLine($"{guid}: {DateTime.Now.ToLongTimeString()}: end");
return "hello";
}
如果我通过多次刷新从 Chrome 调用端点,我会看到它们在我点击刷新后立即执行,并且我在 10 秒后收到响应:
39a20541-a2d6-4cd0-99cd-db0987e273e9: 5:32:44 PM: start
8326d829-28a6-48a2-9874-6506b79488af: 5:32:44 PM: start
aecfbb10-266c-46f8-be3b-bfc2fadf0775: 5:32:44 PM: start
78932f53-37a5-4f26-a56f-b3196256e1cf: 5:32:44 PM: start
39a20541-a2d6-4cd0-99cd-db0987e273e9: 5:32:54 PM: end
8326d829-28a6-48a2-9874-6506b79488af: 5:32:54 PM: end
aecfbb10-266c-46f8-be3b-bfc2fadf0775: 5:32:54 PM: end
78932f53-37a5-4f26-a56f-b3196256e1cf: 5:32:54 PM: end
但是如果我在控制台应用程序中使用此代码进行调用:
var client = new HttpClient();
for (var ii = 0; ii < 10; ii++)
{
client.GetAsync("http://localhost:50621/api/default");
}
Console.ReadKey();
我看到 Console.ReadKey();
立即到达,但请求是两个两个执行的 - 它发出 2 个请求,然后等待 10 秒完成,然后再 2 个,再等 10 秒,等等,甚至虽然据说所有 10 个都已安排。
80546610-c20e-4ff1-b6e5-0fe1688e8803: 5:39:10 PM: start
9bbbb707-9ea7-44da-9d5b-03efc3c4aa47: 5:39:10 PM: start
80546610-c20e-4ff1-b6e5-0fe1688e8803: 5:39:20 PM: end
9bbbb707-9ea7-44da-9d5b-03efc3c4aa47: 5:39:20 PM: end
a146c3ca-a0d2-4588-b60b-156f1febc944: 5:39:20 PM: start
b71bc77f-9bdb-4aa6-936e-c702eb7d49eb: 5:39:20 PM: start
....
那么为什么不立即提出所有请求? HttpClient 是否对未决请求有某种限制?
HttpClient
,以及其他与http相关的类,使用服务点进行http连接管理:
The ServicePoint class handles connections to an Internet resource based on the host information passed in the resource's Uniform Resource Identifier (URI). The initial connection to the resource determines the information that the ServicePoint object maintains, which is then shared by all subsequent requests to that resource.
有ServicePointManager.DefaultConnectionLimit
static 属性,它控制着ServicePoint
对象默认允许的最大并发连接数,默认情况下这个属性的值为2。
这意味着默认情况下您只能与给定主机建立 2 个并发连接。要 "fix" 这个 - 将该数字增加到某个更大的值,通常在应用程序启动时的某个位置。