Как избавиться от HttpClient после его завершения?

Я хочу использовать HttpClient для получения контента для своей веб-страницы.

public async Task<IActionResult> OnGet()
{
    NetworkCredential credentials = new NetworkCredential(Settings.Username, Settings.Password);

    using (HttpClientHandler handler = new HttpClientHandler { Credentials = credentials })
    using (HttpClient httpClient = new HttpClient(handler))
    {
        Content = await httpClient.GetStringAsync(requestUriString);
    }

    return Page();
}

Проблема в том, что мои операторы using вызывают уничтожение объектов HttpClient и HttpClientHandler до завершения GetStringAsync().

Я могу удалить операторы using, но тогда я не могу быть уверен, что соединения будут удалены своевременно.

Обратите внимание, что HttpClient не реализует IAsyncDisposable, поэтому использование await using не вариант.

Как я могу гарантировать, что мои HTTP-объекты будут удалены как можно скорее, не удаляя их до завершения кода?

Код в вашем вопросе даже не скомпилируется. Ваш метод не помечен как асинхронный. Пожалуйста, убедитесь, что вы создали настоящий минимальный воспроизводимый пример . И, конечно же, вы не должны удалять HttpClient, см. Вы используете HttpClient неправильно, и это дестабилизирует ваше программное обеспечение . Одним из простых решений является использование библиотеки, которая позаботится о некоторых из этих деталей за вас, например Flurl.

mason 18.12.2020 21:05

@mason: Спасибо, я исправил проблему. Однако я не столько ищу помощи в отладке моего кода, сколько пытаюсь понять, как следует обрабатывать этот случай.

Jonathan Wood 18.12.2020 21:07

В этом примере Dispose нужно вызывать после окончания GetStringAsync. Возможно ли, что вместо using вы использовали служебный метод, который просто возвращает задачу, а не ожидает ее?

IS4 18.12.2020 23:15
Почему в Python есть оператор &quot;pass&quot;?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
3
3 708
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я нашел эту статью полезной, когда у меня была похожая проблема: https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/ Вот выдержка из кода, который вы ищете:

private static HttpClient Client = new HttpClient();
public static async Task Main(string[] args) 
{
    Console.WriteLine("Starting connections");
    for(int i = 0; i<10; i++)
    {
        var result = await Client.GetAsync("http://aspnetmonsters.com");
        Console.WriteLine(result.StatusCode);
    }
    Console.WriteLine("Connections done");
    Console.ReadLine();
}

Вы ссылаетесь на полезную информацию, но вам нужно объяснить, почему этот код рекомендуется в вашем ответе. Ссылки могут со временем исчезнуть, но мы хотим, чтобы наши ответы по-прежнему были полезными.

mason 18.12.2020 21:13
Ответ принят как подходящий

Таким образом, HttpClient на самом деле немного странный в контексте IDisposable. Несмотря на то, что он реализует интерфейс IDisposable, Microsoft на самом деле не советует помещать его в оператор using.

Если вы используете его в контексте ASP.NET Core, вам следует использовать HttpClientFactory для управления временем жизни ваших HttpClients. В противном случае рекомендуется использовать один статический экземпляр, но следует помнить, что это может привести к другим проблемам, например устареванию DNS.

Интересный. Изучаем это дальше. И я использую .NET 5.

Jonathan Wood 18.12.2020 21:11

О, я действительно забыл, что он вышел. HttpClientFactory также есть в ASP.NET на .NET 5.

sunero4 18.12.2020 21:15

Фактически, фабрика HttpClient управляет временем жизни HttpMessageHandler HttpClient. HttpClients, возвращенные фабрикой, можно безопасно удалять.

Paulo Morgado 18.12.2020 23:59

Другие вопросы по теме