Httpclient — это библиотека по умолчанию, предоставляемая dotnetcore для выполнения HTTP-вызовов из приложения к любому внешнему ресурсу.

HttpClient реализует интерфейс IDisposable, что означает, что вы можете использовать httpclient в блоке использования, и объект удаляется, как только элемент управления выходит из блока использования.

Обычно разработчики идут по этому пути.

Код выглядит следующим образом

using var client = new HttpClient()
client.SendAsync(someHttpRequest);

//client is disposed beyond this point

Вы думаете, что это правильный подход, не так ли? Но это не так.

Проблема с удалением HttpClient

Когда вы делаете запрос через httpclient, он создает соединение сокета, и после удаления объекта соединение сокета устанавливается на закрытие.

Но соединения сокетов не закрываются сразу, есть известная задержка.

Поэтому, когда вы продолжаете создавать и удалять экземпляры http-клиента, соединения сокетов используются, и это приводит к исключению SocketException, потому что больше нет доступных сокетов!

Правильный способ использования

Самый простой правильный способ использования HttpClient — использовать статический экземпляр HttpClient.

Поскольку статический экземпляр используется совместно и не удаляется, у вас будет один экземпляр, доступный для всех вызовов API.

public static HttpClient _mySharedClient = new HttpClient();

// a static instance variable can be used anywhere

Еще лучший способ в dotnetcore — использовать внедрение зависимостей.

Вы можете либо зарегистрировать HttpClient как службу из ConfigureServices, либо использовать интерфейс IHttpClientFactory, который является самым безопасным и рекомендуемым способом в дотнеткор.

// inject HttpClient directly
services.AddHttpClient();

// (or) inject and create with a named client
services.AddHttpClient("myHttpClient");

public class SomeService
{
     private readonly HttpClient _client;

     // inject HttpClient directly
     public SomeService(HttpClient client)
     {
          _client = client;
     }

     // inject IHttpClientFactory use Named Client
     public SomeService(
          IHttpClientFactory clientFactory)
     {
          _client = clientFactory.CreateClient("myHttpClient");
     }
     
}

#aspnetcore #dotnetcore #разработка #http

TL;DR