Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье приводятся дополнительные замечания к справочной документации по этому API.
HttpClient Экземпляр класса выступает в качестве сеанса для отправки HTTP-запросов. Экземпляр HttpClient — это коллекция параметров, применяемых ко всем запросам, выполняемым этим экземпляром. Кроме того, каждый HttpClient экземпляр использует собственный пул подключений, изолируя запросы от запросов, выполняемых другими HttpClient экземплярами.
Инстанцирование
HttpClient предназначен для создания экземпляра один раз и повторного использования в течение всего времени работы приложения. В .NET Core и .NET 5+ HttpClient использует пул подключений в экземпляре обработчика и повторно использует подключение для нескольких запросов. Если создать экземпляр класса HttpClient для каждого запроса, количество сокетов, доступных при тяжелых нагрузках, будет исчерпано. Это исчерпание приведет к SocketException ошибкам.
Дополнительные параметры можно настроить, передав объект "handler", например HttpClientHandler (или SocketsHttpHandler в .NET Core 2.1 или более поздней версии), в качестве части конструктора. Свойства подключения обработчика нельзя изменить после отправки запроса, поэтому одна из причин создания нового экземпляра HttpClient может быть, если необходимо изменить свойства подключения. Если для разных запросов требуются разные параметры, это также может привести к приложению с несколькими HttpClient экземплярами, где каждый экземпляр настроен соответствующим образом, а затем запросы выдаются на соответствующем клиенте.
HttpClient разрешает записи DNS только при создании подключения. Он не отслеживает срок жизни (TTL), указанный DNS-сервером. Если записи DNS регулярно изменяются, что может произойти в некоторых сценариях контейнеров, клиент не будет уважать эти обновления. Чтобы устранить эту проблему, можно ограничить время существования подключения, задав SocketsHttpHandler.PooledConnectionLifetime свойство, чтобы при замене подключения требуется поиск DNS.
public class GoodController : ApiController
{
private static readonly HttpClient httpClient;
static GoodController()
{
var socketsHandler = new SocketsHttpHandler
{
PooledConnectionLifetime = TimeSpan.FromMinutes(2)
};
httpClient = new HttpClient(socketsHandler);
}
}
Вместо создания единственного экземпляра HttpClient, можно использовать IHttpClientFactory для управления несколькими экземплярами HttpClient. Дополнительные сведения см. в руководствах по использованию HttpClient.
Финансовый дериватив
Он HttpClient также служит базовым классом для более специализированных HTTP-клиентов. Примером будет FacebookHttpClient, предоставляющий дополнительные методы, относящиеся к веб-службе Facebook (например, GetFriends
метод). Производные классы не должны переопределять виртуальные методы класса. Вместо этого используйте перегрузку конструктора, которая принимает HttpMessageHandler для настройки любой предварительной или последующей обработки запросов.
Транспорты
HttpClient — это высокоуровневый API, который инкапсулирует низкоуровневую функциональность, доступную на каждой платформе, где он работает.
На каждой платформе HttpClient пытается использовать лучший доступный транспорт:
Хост/среда выполнения | Серверная часть |
---|---|
Windows/.NET Framework | HttpWebRequest |
Windows/Mono | HttpWebRequest |
Windows/UWP | Windows native WinHttpHandler (поддерживающий HTTP/2.0) |
Windows/.NET Core 1.0-2.0 | Windows native WinHttpHandler (поддерживается HTTP 2.0) |
macOS/Mono | HttpWebRequest |
macOS/.NET Core 1.0-2.0 |
libcurl основанный на HTTP транспорт (с поддержкой HTTP 2.0) |
Linux/Mono | HttpWebRequest |
Linux/.NET Core 1.0-2.0 |
libcurl HTTP-транспорт, основанный на (поддерживающий HTTP 2.0) |
.NET Core 2.1 и более поздних версий | System.Net.Http.SocketsHttpHandler |
Пользователи также могут настроить определенный транспорт для HttpClient, вызывая конструктор HttpClient, который принимает HttpMessageHandler как объект.
.NET Framework и Mono
По умолчанию в .NET Framework и Mono HttpWebRequest используется для отправки запросов на сервер. Это поведение можно изменить, указав другой обработчик в одной из перегрузок конструктора с параметром HttpMessageHandler . Если требуются такие функции, как проверка подлинности или кэширование, можно использовать WebRequestHandler для настройки параметров, а экземпляр можно передать конструктору. Возвращаемый обработчик можно передать в перегрузку конструктора, которая имеет HttpMessageHandler параметр.
.NET Core
Начиная с .NET Core 2.1, класс System.Net.Http.SocketsHttpHandler вместо HttpClientHandler предоставляет реализацию, используемую высокоуровневыми сетевыми классами HTTP, такими как HttpClient. Использование SocketsHttpHandler предлагает ряд преимуществ:
- Значительное улучшение производительности по сравнению с предыдущей реализацией.
- Устранение зависимостей платформы, упрощающее развертывание и обслуживание. Например,
libcurl
больше не зависит от .NET Core для macOS и .NET Core для Linux. - Согласованное поведение на всех платформах .NET.
Если это изменение нежелательно, в Windows можно продолжать использовать WinHttpHandler , ссылаясь на его пакет NuGet и передав его в конструктор HttpClient вручную.
Настройка поведения с помощью параметров конфигурации среды выполнения
Некоторые аспекты HttpClientповедения настраиваются с помощью параметров конфигурации среды выполнения. Однако поведение этих коммутаторов отличается от версий .NET. Например, в .NET Core 2.1 – 3.1 можно настроить, используется ли SocketsHttpHandler этот параметр по умолчанию, но этот параметр больше недоступен начиная с .NET 5.
Пулинг соединений
HttpClient группирует HTTP соединения при возможности и использует их для нескольких запросов. Это может иметь значительное преимущество производительности, особенно для HTTPS-запросов, так как подтверждение подключения выполняется только один раз.
Свойства пула подключений можно настроить на HttpClientHandler или SocketsHttpHandler, которые передаются во время создания, включая MaxConnectionsPerServer, PooledConnectionIdleTimeout и PooledConnectionLifetime.
Удаление экземпляра HttpClient закрывает открытые подключения и отменяет любые ожидающие запросы.
Замечание
При одновременной отправке запросов HTTP/1.1 на тот же сервер можно создать новые подключения. Даже при повторном использовании экземпляра HttpClient
, если высокая скорость запросов или имеются ограничения брандмауэра, это может привести к исчерпанию доступных сокетов из-за стандартных таймеров очистки TCP. Чтобы ограничить количество одновременных подключений, можно задать MaxConnectionsPerServer
свойство. По умолчанию число одновременных подключений HTTP/1.1 не ограничено.
Время жизни буферизации и запросов
По умолчанию методы HttpClient (за исключением GetStreamAsync) буферизуют ответы с сервера, считывая весь текст ответа в память, прежде чем возвращать асинхронный результат. Эти запросы будут продолжаться до тех пор, пока не будет выполнено одно из следующих действий:
- Task<TResult> успешно завершает выполнение и результат был возвращён.
- Достигнуто Timeout, и в этом случае Task<TResult> будет отменено.
- Переносимый параметр CancellationToken активируется для некоторых перегрузок методов.
- CancelPendingRequests() вызывается.
- HttpClient удаляется.
Поведение буферизации можно изменить для каждого запроса с помощью параметра HttpCompletionOption, который доступен в некоторых перегрузках методов. Этот аргумент можно использовать для указания того, следует ли Task<TResult> считать его полным после чтения только заголовков ответа или после чтения и буферизации содержимого ответа.
Если приложение, использующее HttpClient и связанные классы в System.Net.Http пространстве имен, намерено скачать большие объемы данных (50 мегабайт или больше), приложение должно передавать эти скачиваемые файлы и не использовать буферизацию по умолчанию. Если вы используете буферизацию по умолчанию, использование памяти клиента будет очень большим, что может привести к значительно снижению производительности.
Потокобезопасность
Следующие методы являются потокобезопасными:
- CancelPendingRequests
- DeleteAsync
- GetAsync
- GetByteArrayAsync
- GetStreamAsync
- GetStringAsync
- PostAsync
- PutAsync
- SendAsync
Прокси
По умолчанию HttpClient считывает конфигурацию прокси-сервера из переменных среды или параметров пользователя или системы в зависимости от платформы. Это поведение можно изменить, передав WebProxy или IWebProxy в порядке приоритета:
- Свойство Proxy HttpClientHandler, переданное при создании HttpClient
- Статичное DefaultProxy свойство (влияет на все экземпляры)
Вы можете отключить прокси-сервер с помощью UseProxy. Конфигурация по умолчанию для пользователей Windows заключается в попытке и обнаружении прокси-сервера с помощью обнаружения сети, что может быть медленно. Для приложений с высокой пропускной способностью, где известно, что прокси-сервер не требуется, следует отключить прокси-сервер.
Параметры прокси-сервера (например Credentials), необходимо изменить только перед первым запросом с помощью HttpClient. Изменения, внесенные после первого использования HttpClient, могут не отражаться в последующих запросах.
тайм-ауты
Вы можете использовать Timeout, чтобы задать время ожидания по умолчанию для всех HTTP-запросов из экземпляра HttpClient. Время ожидания применяется только к методам xxxAsync, которые вызывают инициирование запроса или ответа. Если время ожидания истекло, запрос для Task<TResult> отменяется.
Если вы передаете экземпляр SocketsHttpHandler при создании объекта HttpClient, можно задать несколько дополнительных тайм-аутов.
Недвижимость | Описание |
---|---|
ConnectTimeout | Указывает время ожидания, используемое при создании нового TCP-соединения по запросу. Если истекает время ожидания, запрос Task<TResult> отменяется. |
PooledConnectionLifetime | Указывает время ожидания, используемое для каждого подключения в пуле соединений. Если подключение неактивно, подключение немедленно закрывается; в противном случае соединение закрывается в конце текущего запроса. |
PooledConnectionIdleTimeout | Если подключение в пуле подключений неактивно в течение этого времени, подключение закрывается. |
Expect100ContinueTimeout | Если запрос имеет заголовок "Ожидает: 100-continue", он задерживает отправку содержимого до истечения тайм-аута или до получения ответа "100-continue". |
HttpClient разрешает только записи DNS при создании подключений. Он не отслеживает срок жизни (TTL), указанный DNS-сервером. Если записи DNS изменяются регулярно, что может произойти в некоторых сценариях контейнеров, можно использовать PooledConnectionLifetime для ограничения времени существования подключения, чтобы при замене подключения требуется поиск DNS.