Проблема с HttpClient
Когда вы создаете много экземпляров HttpClient
, вы можете столкнуться с проблемой Socket Exhaustion.
Это происходит потому, что сокеты — это ограниченный ресурс, и они освобождаются не в тот момент, когда вы их «утилизируете», а немного позже. Поэтому, когда вы создаете много клиентов, вы можете исчерпать доступные сокеты.
Даже при использовании утверждений using
вы можете столкнуться с проблемой исчерпания сокетов.
class ResourceChecker
{
public async Task<bool> ResourceExists(string url)
{
using (HttpClient client = new HttpClient())
{
var response = await client.GetAsync(url);
return response.IsSuccessStatusCode;
}
}
}
На самом деле, реальная проблема заключается в утилизации экземпляров HttpMessageHandler
. Имея простые объекты HttpClient
, вы не имеете никакого контроля над ними.
Представляем HttpClientFactory
Класс HttpClientFactory
создает для вас экземпляры HttpClient
.
class ResourceChecker
{
private IHttpClientFactory _httpClientFactory;
public ResourceChecker(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public async Task<bool> ResourceExists(string url)
{
HttpClient client = _httpClientFactory.CreateClient();
var response = await client.GetAsync(url);
return response.IsSuccessStatusCode;
}
}
Цель IHttpClientFactory
— решить эту проблему с помощью HttpMessageHandler
.
Интересной особенностью IHttpClientFactory
является то, что вы можете настроить его с помощью некоторых общих конфигураций, которые будут применяться ко всем экземплярам HttpClient
, созданным определенным образом. Например, вы можете определить HTTP-заголовки, базовый URL и другие свойства в одной точке, и эти свойства будут применяться везде.
Как добавить его в API .NET Core или на веб-сайты
Как вы можете использовать HttpClientFactory в своих проектах .NET?
Если у вас есть класс Startup, вы можете просто добавить инструкцию в метод ConfigureServices
:
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient();
}
Вы можете найти этот метод расширения в пространстве имен Microsoft.Extensions.DependencyInjection
.
Подведение итогов
В этой статье мы рассмотрели, почему не следует инстанцировать HttpClients вручную, а лучше использовать IHttpClientFactory
.
Счастливого кодинга!
🐧