Skip to content

Commit ad8220d

Browse files
authored
Add HttpClient instancing info (dotnet#8098)
1 parent 1925f3b commit ad8220d

File tree

1 file changed

+20
-27
lines changed

1 file changed

+20
-27
lines changed

xml/System.Net.Http/HttpClient.xml

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -42,38 +42,30 @@ The <xref:System.Net.Http.HttpClient> class instance acts as a session to send H
4242
4343
### Instancing
4444
45-
<xref:System.Net.Http.HttpClient> is intended to be instantiated once and reused throughout the life of an application. HttpClient is designed to pool connections and reuse a connection across multiple requests. If you instantiate an HttpClient class for every request, the number of sockets available under heavy loads will be exhausted. This exhaustion will result in <xref:System.Net.Sockets.SocketException> errors. Following is an example that uses HttpClient correctly.
45+
<xref:System.Net.Http.HttpClient> is intended to be instantiated once and reused throughout the life of an application. In .NET Core and .NET 5+, HttpClient pools connections inside the handler instance and reuses a connection across multiple requests. If you instantiate an HttpClient class for every request, the number of sockets available under heavy loads will be exhausted. This exhaustion will result in <xref:System.Net.Sockets.SocketException> errors.
46+
47+
You can configure additional options by passing in a "handler", such as <xref:System.Net.Http.HttpClientHandler> (or <xref:System.Net.Http.SocketsHttpHandler> in .NET Core 2.1 or later), as part of the constructor. The connection properties on the handler cannot be changed once a request has been submitted, so one reason to create a new HttpClient instance would be if you need to change the connection properties. If different requests require different settings, this may also lead to an application having multiple <xref:System.Net.Http.HttpClient> instances, where each instance is configured appropriately, and then requests are issued on the relevant client.
48+
49+
HttpClient only resolves DNS entries when a connection is created. It does not track any time to live (TTL) durations specified by the DNS server. If DNS entries change regularly, which can happen in some container scenarios, the client won't respect those updates. To solve this issue, you can limit the lifetime of the connection by setting the <xref:System.Net.Http.SocketsHttpHandler.PooledConnectionLifetime?displayProperty=nameWithType> property, so that DNS lookup is required when the connection is replaced.
4650
4751
```csharp
4852
public class GoodController : ApiController
4953
{
50-
private static readonly HttpClient HttpClient;
54+
private static readonly HttpClient httpClient;
5155
5256
static GoodController()
5357
{
54-
HttpClient = new HttpClient();
58+
var socketsHandler = new SocketsHttpHandler
59+
{
60+
PooledConnectionLifetime = TimeSpan.FromMinutes(2)
61+
};
62+
63+
httpClient = new HttpClient(socketsHandler);
5564
}
5665
}
5766
```
5867
59-
```fsharp
60-
type GoodController() =
61-
inherit ApiController()
62-
let httpClient = new HttpClient()
63-
```
64-
65-
```vb
66-
Public Class GoodController
67-
Inherits ApiController
68-
69-
Private Shared ReadOnly HttpClient As HttpClient
70-
71-
Shared Sub New()
72-
HttpClient = New HttpClient()
73-
End Sub
74-
End Class
75-
```
76-
You can configure additional options by passing in a "handler", such as <xref:System.Net.Http.HttpClientHandler> (or <xref:System.Net.Http.SocketsHttpHandler> in .NET Core 2.1 or later), as part of the constructor. The connection properties on the handler cannot be changed once a request has been submitted, so one reason to create a new HttpClient instance would be if you need to change the connection properties. If different requests require different settings, this may also lead to an application having multiple <xref:System.Net.Http.HttpClient> instances, where each instance is configured appropriately, and then requests are issued on the relevant client.
68+
As an alternative to creating only one HttpClient instance, you can also use <xref:System.Net.Http.IHttpClientFactory> to manage the HttpClient instances for you. For more information, see [Guidelines for using HttpClient](/dotnet/fundamentals/networking/httpclient-guidelines).
7769
7870
### Derivation
7971
@@ -128,6 +120,9 @@ Connection pool properties can be configured on a <xref:System.Net.Http.HttpClie
128120
129121
Disposing of the HttpClient instance closes the open connections and cancels any pending requests.
130122
123+
> [!NOTE]
124+
> If you concurrently send HTTP/1.1 requests to the same server, new connections can be created. Even if you reuse the `HttpClient` instance, if the rate of requests is high, or if there are any firewall limitations, that can exhaust the available sockets because of default TCP cleanup timers. To limit the number of concurrent connections, you can set the `MaxConnectionsPerServer` property. By default, the number of concurrent HTTP/1.1 connections is unlimited.
125+
131126
### Buffering and request lifetime
132127
133128
By default, HttpClient methods (except <xref:System.Net.Http.HttpClient.GetStreamAsync%2A>) buffer the responses from the server, reading all the response body into memory before returning the async result. Those requests will continue until one of the following occurs:
@@ -180,7 +175,8 @@ You can set some additional timeouts if you pass in a <xref:System.Net.Http.Sock
180175
181176
HttpClient only resolves DNS entries when the connections are created. It does not track any time to live (TTL) durations specified by the DNS server. If DNS entries are changing regularly, which can happen in some container scenarios, you can use the <xref:System.Net.Http.SocketsHttpHandler.PooledConnectionLifetime> to limit the lifetime of the connection so that DNS lookup is required when replacing the connection.
182177
183-
## Examples
178+
## Examples
179+
184180
:::code language="csharp" source="~/snippets/csharp/System.Net.Http/HttpClient/source.cs" id="Snippet1":::
185181
:::code language="fsharp" source="~/snippets/fsharp/System.Net.Http/HttpClient/source.fs" id="Snippet1":::
186182
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_Misc/system.net.http.httpclient/vb/source.vb" id="Snippet1":::
@@ -189,11 +185,8 @@ HttpClient only resolves DNS entries when the connections are created. It does n
189185
190186
]]></format>
191187
</remarks>
192-
<related type="ExternalDocumentation" href="https://go.microsoft.com/fwlink/?LinkID=245696">Connecting to a web service</related>
193-
<related type="ExternalDocumentation" href="https://go.microsoft.com/fwlink/?LinkId=245697">Quickstart: Connecting using HttpClient </related>
194-
<related type="ExternalDocumentation" href="https://go.microsoft.com/fwlink/?LinkId=245699">How to use HttpClient handlers</related>
195-
<related type="ExternalDocumentation" href="https://go.microsoft.com/fwlink/?LinkId=245698">How to secure HttpClient connections</related>
196-
<related type="ExternalDocumentation" href="https://go.microsoft.com/fwlink/?LinkId=242550">HttpClient Sample</related>
188+
<related type="ExternalDocumentation" href="/dotnet/fundamentals/networking/httpclient-guidelines">Guidelines for using HttpClient</related>
189+
<related type="ExternalDocumentation" href="/samples/dotnet/samples/console-webapiclient/">HttpClient Sample</related>
197190
</Docs>
198191
<Members>
199192
<MemberGroup MemberName=".ctor">

0 commit comments

Comments
 (0)