![](/img/trans.png)
[英]In c# how to know if a weak referenced object is going to be garbage collected?
[英]C# Weak-referenced object alive after `using` block
基於這個先前的問題,我想看看不處理HttpClient
object 是否會造成泄漏(確實如此,但這里沒有什么新東西)。 但是,我還發現,如果我不處理HttpClient
object,則返回的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下編譯,output如下:
Alive: True
Alive: False
編輯:使用 .NET Core,我得到了預期的結果:
Alive: False
Alive: False
我的問題是,為什么HttpResponseMessage
在我處理它之后仍然存在,但前提是我不處理它的創建者?
(查看HttpClient
的來源,我發現確實存在對所持有的HttpResponseMessage
的引用,但這深入到異步領域,讓我真正了解發生了什么( SetTaskCompleted
-> TaskCompletionSource<>.TrySetResult()
))
首先,我們需要看看這個MSDN - HttpClient Class 。
HttpClient 旨在為每個應用程序實例化一次,而不是每次使用。 見備注。
無論如何,這就是你錯過的。
public void CallServiceTest()
{
var wRef2 = CallInItsOwnScope(() =>
{
// HttpClient -> HttpMessageInvoker(IDisposable), so it can be disposed.
using (var client = new HttpClient())
{
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();
Assert.IsFalse(wRef2.IsAlive);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.