【发布时间】:2020-07-14 01:14:29
【问题描述】:
基于on this previous question,我想看看不释放HttpClient 对象是否会造成泄漏(确实如此,但这里没有什么新鲜事)。但是,我还发现,如果我不处置 HttpClient 对象,则返回的 HttpResponseMessage 不会被垃圾回收。
这是测试。我提供了一个reproducing fiddle here。
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
编辑: 使用 .NET Core,我得到了预期的结果:
Alive: False
Alive: False
我的问题是,为什么 HttpResponseMessage 在我处置后仍然活着,但前提是我不处置它的创建者?
(查看HttpClient 的来源,我发现确实有对HttpResponseMessage 的引用,但这对我来说深入到异步领域才能真正理解发生了什么(SetTaskCompleted -> @ 987654334@))
【问题讨论】:
-
你为什么要
Dispose你的HttpClient。一般的建议是让他们永远活着。 -
我试图理解为什么
HttpResponse对象会泄漏。我不担心HttpClient,事实上,我担心过于频繁地处理它会导致套接字耗尽。 -
我收到了
False、False,因此如果您希望其他人看到您所看到的内容,这里缺少一些细节。 -
我有一个普通的 .net framework 4.7.2 控制台应用程序,它返回上面的结果。对于这两种情况,使用 .net 核心控制台应用程序都会返回 false。
-
达米安,您应该至少等一会才开始结束问题。这是一个小提琴给你看。 dotnetfiddle.net/Xo6iKu
标签: c# .net garbage-collection