Основываясь на на этом предыдущем вопросе , я хотел посмотреть, не приводит ли не удаление объекта HttpClient
к утечкам (что происходит, но здесь нет ничего нового). Однако я также обнаружил, что если я не удаляю объект HttpClient
, возвращаемый HttpResponseMessage
не является сборщиком мусора.
Вот тест. Здесь я предоставил воспроизводящую скрипку .
using System;
using System.Net.Http;
namespace HttpClientTest
{
internal static class Program
{
private static T CallInItsOwnScope<T>(Func<T> getter)
{
return getter();
}
private static void Main()
{
var client = new HttpClient();
var wRef2 = CallInItsOwnScope(() =>
{
using (var response = client.GetAsync(new Uri("https://postman-echo.com/get?foo1=bar1&foo2=bar2")).Result)
{
return new WeakReference(response);
}
});
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine($"Alive: {wRef2.IsAlive}");
client.Dispose();
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine($"Alive: {wRef2.IsAlive}");
Console.ReadKey();
}
}
}
Компиляция под. NET Framework 4.7.2, результат будет следующим:
Alive: True
Alive: False
Edit: using. NET Core, я получаю ожидаемый результат:
Alive: False
Alive: False
Мой вопрос: почему HttpResponseMessage
все еще жив после того, как я его удалил, но только если я не избавляться от его создателя?
(Глядя на источники HttpClient
, я обнаружил, что действительно есть ссылка на HttpResponseMessage
, удерживаемый, но для меня это глубоко в асинхронной c земле чтобы действительно понять, что происходит (SetTaskCompleted
-> TaskCompletionSource<>.TrySetResult()
))