Должен ли я использовать оператор Using с HttpClient? - PullRequest
2 голосов
/ 28 марта 2019

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

Я прочитал эту статью https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/. Должен ли я действительно не использовать оператор using? Также я делаю синхронные вызовы API. Имеет ли это какое-либо влияние? Что я сделал эффективно?

Вот мой код:

[HttpGet]
[Route("api/apiname")]     
public String GetNumberofP([FromUri]GetNumberofPRequest getNPRequest){          

    var request = JsonConvert.SerializeObject(getNPRequest);
    string errorMessage = "";           

    try{              
         httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.gettoken());

         var response = httpClient.GetAsync("api/MobileApp/GetNumberP?"
                      + "strCardNumber=" + getNPRequest.strCardNumber
                     + "&strDateOfBirth=" + getNPRequest.strDateOfBirth).Result;
         return response;
    }            
    catch (Exception e){                
        throw utils.ReturnException("GetNumberofP", e, errorMessage);           
    }      
}

Ответы [ 2 ]

8 голосов
/ 28 марта 2019

HttpClient не нужно утилизировать, и вы должны держаться за него, чтобы использовать его позже.

Одна вещь, которую вы можете использовать (из нити, которую вы связали):

Вы просто предоставляете свои HttpClient фабричные и методы утилизации, а LimitedPool делает все остальное:

_httpClientPool = new LimitedPool<httpclient>(
CreateHttpClient, client => client.Dispose(), HttpClientLifetime);

using (var httpClientContainer = _httpClientPool.Get())
{ ... use httpClientContainer.Value ... }

Когда удаляется httpClientContainer, HttpClient фактически возвращается обратно в пул длядругие темы для использования.Когда время жизни истечет, следующая утилита в конечном итоге вызовет метод Dispose.

См. Код здесь

Альтернатива для .Net Core

Реализуйте его, как описано в этом документе .

Чтобы зарегистрировать IHttpClientFactory, вызовите метод расширения AddHttpClient для IServiceCollection внутри метода Startup.ConfigureServices.

services.AddHttpClient();

После регистрации код может принимать IHttpClientFactory везде, где сервисы могут быть внедрены с помощью внедрения зависимостей (DI).IHttpClientFactory можно использовать для создания экземпляра HttpClient:

public MyConstructor(IHttpClientFactory clientFactory)
{
    _clientFactory = clientFactory;
}

public async Task OnGet()
{
    ....
    var client = _clientFactory.CreateClient();

    var response = await client.SendAsync(request);
    ...
}

Не нужно использовать using().

1 голос
/ 28 марта 2019

Если вы используете ядро ​​asp.net, правильный способ использования HttpClient объясняется в этой статье Microsoft:

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-2.2#typed-clients

Я обычно использую подход типизированного клиента, описанный в статье.

Это в основном означает, что я делегирую в основной контейнер asp.net инъекцию http-клиента в мой класс (класс контроллера, сервис, фильтр и т. Д.)

Таким образом, вы можете безопасно изменить http-клиент в своем классе, добавив все необходимые заголовки запроса (вы обычно делаете это внутри конструктора вашего класса).

Вам не нужно вызывать dispose на введенном http-клиенте, вы просто используете его.

Основной контейнер asp.net будет управлять временем жизни клиента http для вас и пулом ресурсов, используемым экземплярами клиента http, чтобы ваше приложение не пропускало ресурсы. Все это происходит автоматически.

Не использовать синхронизирующие вызовы. Сделайте ваш метод действия асинхронным и дождитесь асинхронных методов http-клиента. Ядро Asp.net полностью поддерживает асинхронный код и делать запросы на блокировку не имеет смысла, поэтому вы ограничите масштабируемость вашего приложения.

...