Reputation: 79665
Why is HttpClient.GetAsync()/PostAsync()/SendAsync() etc only scheduling 2 requests at a time?
I tested this in the following way:
I have an async GET method that waits without blocking for 10 seconds before responding.
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";
}
If I call the endpoint from Chrome by refreshing multiple times I see they all execute as soon as I hit refresh, and I receive the responses 10 seconds later:
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
But if I make calls using this code in a console application:
var client = new HttpClient();
for (var ii = 0; ii < 10; ii++)
{
client.GetAsync("http://localhost:50621/api/default");
}
Console.ReadKey();
I see that Console.ReadKey();
is reached immediately, but the requests are executed two by two - it makes 2 requests, then waits 10 seconds to finish, then another 2, another 10 seconds, etc., even though all 10 have been supposedly scheduled.
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
....
So why aren't all the requests made immediately? Does HttpClient have some sort of a limit on pending requests?
Upvotes: 3
Views: 1299
Reputation: 101583
HttpClient
, as well as other http-related classes, uses service points for http connection management:
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.
There is ServicePointManager.DefaultConnectionLimit
static property, which controls default maximum number of concurrent connections allowed for ServicePoint
object, and by default this property has value 2.
That means that by default you can only have 2 concurrent connections to given host. To "fix" this - increase that number to some bigger value, usually somewhere at startup of your application.
Upvotes: 9