Я хочу использовать 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-объекты будут удалены как можно скорее, не удаляя их до завершения кода?
@mason: Спасибо, я исправил проблему. Однако я не столько ищу помощи в отладке моего кода, сколько пытаюсь понять, как следует обрабатывать этот случай.
В этом примере Dispose нужно вызывать после окончания GetStringAsync. Возможно ли, что вместо using вы использовали служебный метод, который просто возвращает задачу, а не ожидает ее?
Я нашел эту статью полезной, когда у меня была похожая проблема: 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();
}
Вы ссылаетесь на полезную информацию, но вам нужно объяснить, почему этот код рекомендуется в вашем ответе. Ссылки могут со временем исчезнуть, но мы хотим, чтобы наши ответы по-прежнему были полезными.
Таким образом, HttpClient на самом деле немного странный в контексте IDisposable. Несмотря на то, что он реализует интерфейс IDisposable, Microsoft на самом деле не советует помещать его в оператор using.
Если вы используете его в контексте ASP.NET Core, вам следует использовать HttpClientFactory для управления временем жизни ваших HttpClients. В противном случае рекомендуется использовать один статический экземпляр, но следует помнить, что это может привести к другим проблемам, например устареванию DNS.
Интересный. Изучаем это дальше. И я использую .NET 5.
О, я действительно забыл, что он вышел. HttpClientFactory также есть в ASP.NET на .NET 5.
Фактически, фабрика HttpClient управляет временем жизни HttpMessageHandler HttpClient. HttpClients, возвращенные фабрикой, можно безопасно удалять.
Код в вашем вопросе даже не скомпилируется. Ваш метод не помечен как асинхронный. Пожалуйста, убедитесь, что вы создали настоящий минимальный воспроизводимый пример . И, конечно же, вы не должны удалять HttpClient, см. Вы используете HttpClient неправильно, и это дестабилизирует ваше программное обеспечение . Одним из простых решений является использование библиотеки, которая позаботится о некоторых из этих деталей за вас, например Flurl.