-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Updated HttpClient main topic to address user feedback from issues. #3986
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 3 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
d7800cf
Updated HttpClient main topic to address user feedback from issues.
samsp-msft d48d699
fixed xrefs
samsp-msft e6d19dc
Merge branch 'master' into httpclientfixup
BillWagner 6394b41
Update xml/System.Net.Http/HttpClient.xml
samsp-msft a03c45e
Update xml/System.Net.Http/HttpClient.xml
samsp-msft 5603ab5
Update xml/System.Net.Http/HttpClient.xml
samsp-msft ba47371
Update xml/System.Net.Http/HttpClient.xml
samsp-msft 50080b4
Update xml/System.Net.Http/HttpClient.xml
samsp-msft 64395e5
Merge branch 'main' into httpclientfixup
samsp-msft 31dacf7
Update HttpClient.xml
samsp-msft 078435c
Update HttpClient.xml
samsp-msft 19922bc
Apply suggestions from code review
gewarren aabe793
Fix grammar
gewarren 918b6fc
Minor touch-ups
gewarren 89367bb
resolve merge conflict
gewarren File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,37 +30,10 @@ | |
|
||
## Remarks | ||
The <xref:System.Net.Http.HttpClient> class instance acts as a session to send HTTP requests. An <xref:System.Net.Http.HttpClient> instance is a collection of settings applied to all requests executed by that instance. In addition, every <xref:System.Net.Http.HttpClient> instance uses its own connection pool, isolating its requests from requests executed by other <xref:System.Net.Http.HttpClient> instances. | ||
|
||
The <xref:System.Net.Http.HttpClient> also acts as a base class for more specific HTTP clients. An example would be a FacebookHttpClient providing additional methods specific to a Facebook web service (a GetFriends method, for instance). Derived classes should not override the virtual methods on the class. Instead, use a constructor overload that accepts <xref:System.Net.Http.HttpMessageHandler> to configure any pre- or post-request processing instead. | ||
|
||
By default on .NET Framework and Mono, <xref:System.Net.HttpWebRequest> is used to send requests to the server. This behavior can be modified by specifying a different channel in one of the constructor overloads taking a <xref:System.Net.Http.HttpMessageHandler> instance as parameter. If features like authentication or caching are required, <xref:System.Net.Http.WebRequestHandler> can be used to configure settings and the instance can be passed to the constructor. The returned handler can be passed to one of the constructor overloads taking a <xref:System.Net.Http.HttpMessageHandler> parameter. | ||
|
||
If an app using <xref:System.Net.Http.HttpClient> and related classes in the <xref:System.Net.Http> namespace intends to download large amounts of data (50 megabytes or more), then the app should stream those downloads and not use the default buffering. If the default buffering is used the client memory usage will get very large, potentially resulting in substantially reduced performance. | ||
|
||
Properties of <xref:System.Net.Http.HttpClient> should not be modified while there are outstanding requests, because it is not thread-safe. | ||
### Instancing | ||
|
||
|
||
The following methods are thread safe: | ||
|
||
1. <xref:System.Net.Http.HttpClient.CancelPendingRequests%2A> | ||
|
||
2. <xref:System.Net.Http.HttpClient.DeleteAsync%2A> | ||
|
||
3. <xref:System.Net.Http.HttpClient.GetAsync%2A> | ||
|
||
4. <xref:System.Net.Http.HttpClient.GetByteArrayAsync%2A> | ||
|
||
5. <xref:System.Net.Http.HttpClient.GetStreamAsync%2A> | ||
|
||
6. <xref:System.Net.Http.HttpClient.GetStringAsync%2A> | ||
|
||
7. <xref:System.Net.Http.HttpClient.PostAsync%2A> | ||
|
||
8. <xref:System.Net.Http.HttpClient.PutAsync%2A> | ||
|
||
9. <xref:System.Net.Http.HttpClient.SendAsync%2A> | ||
|
||
<xref:System.Net.Http.HttpClient> is intended to be instantiated once and re-used throughout the life of an application. Instantiating an HttpClient class for every request will exhaust the number of sockets available under heavy loads. This will result in SocketException errors. Below is an example using HttpClient correctly. | ||
<xref:System.Net.Http.HttpClient> is intended to be instantiated once and re-used throughout the life of an application. HttpClient is designed to pool connections, and re-use a connection across multiple requests. Instantiating an HttpClient class for every request will exhaust the number of sockets available under heavy loads. This will result in SocketException errors. Below is an example using HttpClient correctly. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Though they'll be wrapped when actually emerging into user code, right? e.g. in an HttpRequestException?
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```csharp | ||
public class GoodController : ApiController | ||
|
@@ -85,6 +58,13 @@ public class GoodController : ApiController | |
End Sub | ||
End Class | ||
``` | ||
Additional options can be configured by passing in a <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 the connection properties need to be changed. | ||
samsp-msft marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Derivation | ||
|
||
The <xref:System.Net.Http.HttpClient> also acts as a base class for more specific HTTP clients. An example would be a FacebookHttpClient providing additional methods specific to a Facebook web service (a GetFriends method, for instance). Derived classes should not override the virtual methods on the class. Instead, use a constructor overload that accepts <xref:System.Net.Http.HttpMessageHandler> to configure any pre- or post-request processing instead. | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Transports | ||
|
||
The <xref:System.Net.Http.HttpClient> is a high-level API that wraps the lower-level functionality available on each platform where it runs. | ||
|
||
|
@@ -107,7 +87,11 @@ On each platform, <xref:System.Net.Http.HttpClient> tries to use the best availa | |
|
||
Users can also configure a specific transport for <xref:System.Net.Http.HttpClient> by invoking the <xref:System.Net.Http.HttpClient.%23ctor*> constructor that takes an <xref:System.Net.Http.HttpMessageHandler>. | ||
|
||
### HttpClient and .NET Core | ||
#### .NET Framework & Mono | ||
|
||
By default on .NET Framework and Mono, <xref:System.Net.HttpWebRequest> is used to send requests to the server. This behavior can be modified by specifying a different channel in one of the constructor overloads taking a <xref:System.Net.Http.HttpMessageHandler> instance as parameter. If features like authentication or caching are required, <xref:System.Net.Http.WebRequestHandler> can be used to configure settings and the instance can be passed to the constructor. The returned handler can be passed to one of the constructor overloads taking a <xref:System.Net.Http.HttpMessageHandler> parameter. | ||
samsp-msft marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
#### .NET Core | ||
|
||
Starting with .NET Core 2.1, the <xref:System.Net.Http.SocketsHttpHandler?displayProperty=nameWithType> class instead of `HttpClientHandler` provides the implementation used by higher-level HTTP networking classes such as `HttpClient`. The use of <xref:System.Net.Http.SocketsHttpHandler> offers a number of advantages: | ||
samsp-msft marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
@@ -140,6 +124,74 @@ If this change is undesirable, you can configure your application to use the old | |
|
||
- By defining an environment variable named `DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER` and setting it to either `false` or 0. | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Connection Pooling | ||
|
||
HttpClient will pool HTTP connections where possible, and use them for more than one request. This can have a significant performance benefit, especially for HTTPS requests, as the connection handshake is only done once. | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Connection pool properties can be configured on a <xref:System.Net.Http.HttpClientHandler> or <xref:System.Net.Http.SocketsHttpHandler> passed in during construction, including <xref:System.Net.Http.HttpClientHandler.MaxConnectionsPerServer>, <xref:System.Net.Http.SocketsHttpHandler.PooledConnectionIdleTimeout> and <xref:System.Net.Http.SocketsHttpHandler.PooledConnectionLifetime>. | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Todo: Disposing of the HttpClient instance will close the open connections and cancel any pending requests. | ||
samsp-msft marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Buffering & Request lifetime | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
By default, HttpClient methods (except <xref:System.Net.Http.HttpClient.GetStreamAsync>) will 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: | ||
samsp-msft marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
* The <xref:System.Threading.Tasks.Task%601> succeds and returns a result | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* The <xref:System.Net.Http.HttpClient.Timeout> is reached, in which case the <xref:System.Threading.Tasks.Task%601> will be cancelled | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* The <xref:System.Threading.CancellationToken> passable to some method overloads is fired | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* <xref:System.Net.Http.HttpClient.CancelPendingRequests> is called | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* The HttpClient is disposed | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
The buffering behavior can be changed on a per request basis using the HttpCompletionOption parameter available on some method overloads. This can be used to specify if the <xref:System.Threading.Tasks.Task%601> should be considered complete after reading just the response headers, or having read and buffered the response content. | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
If an app using <xref:System.Net.Http.HttpClient> and related classes in the <xref:System.Net.Http> namespace intends to download large amounts of data (50 megabytes or more), then the app should stream those downloads and not use the default buffering. If the default buffering is used the client memory usage will get very large, potentially resulting in substantially reduced performance. | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Thread Safety | ||
|
||
The following methods are thread safe: | ||
|
||
1. <xref:System.Net.Http.HttpClient.CancelPendingRequests%2A> | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
2. <xref:System.Net.Http.HttpClient.DeleteAsync%2A> | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
3. <xref:System.Net.Http.HttpClient.GetAsync%2A> | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
4. <xref:System.Net.Http.HttpClient.GetByteArrayAsync%2A> | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
5. <xref:System.Net.Http.HttpClient.GetStreamAsync%2A> | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
6. <xref:System.Net.Http.HttpClient.GetStringAsync%2A> | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
7. <xref:System.Net.Http.HttpClient.PostAsync%2A> | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
8. <xref:System.Net.Http.HttpClient.PutAsync%2A> | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
9. <xref:System.Net.Http.HttpClient.SendAsync%2A> | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Proxies | ||
|
||
By deafult HttpClient will read proxy configuration from environment variables or user / system settings depending on the platform being used. This can be changed by passing a <xref:System.Net.WebProxy> or <xref:System.Net.IWebProxy> to, in order of precedence: | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
* The <xref:System.Net.Http.HttpClientHandler.Proxy> property on a HttpClientHandler passed in during HttpClient construction | ||
* The <xref:System.Net.http.HttpClient.DefaultProxy> static property (affects all instanes) | ||
samsp-msft marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
The proxy can be disabled using <xref:System.Net.Http.HttpClientHandler.UseProxy>. The default configuration for Windows users is to try and detect a proxy using network discovery which can be slow. For high througput applications where its known that a proxy is not required, the proxy should be disabled. | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Timeouts | ||
|
||
HttpClient.Timeout can be used to set a default timeout for all Http requests from the HttpClient instance. The timeout only applies to the xxxAsync methods that cause a request/response to be initiated. If the timeout is reached, the <xref:System.Threading.Tasks.Task%601> for that request will be cancelled. | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Some Additional timeouts can be set if you construct the HttpClient passing in a <xref:System.Net.Http.SocketsHttpHandler> instance: | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
| **Property** | **Description**| | ||
| ------------ | -------------- | | ||
| <xref:System.Net.Http.SocketsHttpHandler.ConnectTimeout> | Specifies a timeout that is used when a request requires a new TCP connection to be created. If the timout occurs the request <xref:System.Threading.Tasks.Task%601> is cancelled. | | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| <xref:System.Net.Http.SocketsHttpHandler.PooledConnectionLifetime> | Specifies a timeout to be used for each connection in the connection pool. If the connection is idle, it is immediately closed, otherwise at the end of the current request. | | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| <xref:System.Net.Http.SocketsHttpHandler.PooledConnectionIdleTimeout> | If a connection in the connection pool is idle for this long the connection will be closed. | | ||
gewarren marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| <xref:System.Net.Http.SocketsHttpHandler.Expect100ContinueTimeout> | If request has an "Expect: 100-continue" header, it will delay sending the body until the timeout or a "100-continue" response has been recieved. | | ||
samsp-msft marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
HttpClient will only resolve DNS entries when the connections are created, it does not track any TTL durations specified by the DNS server. If DNS entries are changing regularly, which can happen in some container scenarios, the <xref:System.Net.Http.SocketsHttpHandler.PooledConnectionLifetime> can be used to limit the lifetime of the connection so that DNS will be requiried when replacing the connection. | ||
samsp-msft marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Examples | ||
[!code-csharp[System.Net.Http.HttpClient#1](~/samples/snippets/csharp/VS_Snippets_Misc/system.net.http.httpclient/cs/source.cs#1)] | ||
[!code-vb[System.Net.Http.HttpClient#1](~/samples/snippets/visualbasic/VS_Snippets_Misc/system.net.http.httpclient/vb/source.vb#1)] | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.