gpt4 book ai didi

c# - 当 WeakReference 引用委托(delegate)时 GC 不收集?

转载 作者:太空狗 更新时间:2023-10-29 21:34:49 24 4
gpt4 key购买 nike

在我看来,当我在对象类的委托(delegate)方法上使用 WeakReference 类时,该对象类会被 GC 收集,但它的另一个副本仍然驻留在 弱引用?

我觉得很难用语言来解释。我举个例子。我有以下名为 TestObject 的对象类:

class TestObject
{
public string message = "";

private delegate string deleg();

public TestObject(string msg)
{
message = msg;
}

public Delegate GetMethod()
{
deleg tmp = this.TestMethod;
return tmp;
}

public string TestMethod()
{
return message;
}

}

现在,在我的主应用程序中,我尝试通过 WeakReference 引用 TestObject 中的方法 TestMethod。目的是当所有硬引用都消失时,TestObject 可以被 GC 收集。这是我的主要应用程序的样子:

static void Main(string[] args)
{
var list = new List<WeakReference>();
var obj = new TestObject("Hello 1");
list.Add(new WeakReference(obj.GetMethod()));
Console.WriteLine("Initial obj: " + ((Delegate)list[0].Target).DynamicInvoke()); //Works fine
obj = null; //Now, obj is set to null, the TestObject("Hello 1") can be collected by GC
GC.Collect(); //Force GC
Console.WriteLine("Is obj null: " + ((obj) == null ? "True" : "False"));
Console.WriteLine("After GC collection: " + ((Delegate)list[0].Target).DynamicInvoke());
Console.ReadKey();
}

这是我运行上面代码时的输出:

enter image description here

奇怪的是。 在第一行obj 可以打印"Hello 1" 因为它刚刚初始化并且obj 持有一个对 TestObject 的引用。全对了。接下来,obj 被设置为 null 并且 obj = null 并且 GC 被强制收集。因此,在输出的第二行objtrue 为 null。最后 在最后一行,因为 GC 已经收集了 obj,我希望它要么抛出一个 NullReferenceException,要么什么都不打印在输出上。然而,它实际上打印了与输出的第一行相同的内容! TestObject 不应该在此时由 GC 收集吗?!

这引出了一个问题,即在我将 obj 设置为 null 后,最初保存在 obj 中的 TestObject 是否后来被 GC 收集。

如果我将整个对象传递给 WeakReference,即 new WeakReference(obj),而不是将委托(delegate)传递给 WeakReference,它本来可以完美运行的。

不幸的是,在我的代码中,我需要向 WeakReference 传递一个委托(delegate)。我怎样才能让 WeakReference 正常工作,以便 GC 可以通过仅引用委托(delegate)来收集对象?

最佳答案

我认为问题出在您的测试中 - 而不是在框架中。将局部变量设置为 null 似乎并没有达到您的预期。如果我们完全跳过局部变量,我们会在“之后”行得到预期的 NullReferenceException:

static void Main(string[] args)
{
var list = new List<WeakReference>();
//var obj = new TestObject("Hello 1");
list.Add(new WeakReference(new TestObject("Hello 1").GetMethod()));
Console.WriteLine("Initial obj: " + ((Delegate)list[0].Target).DynamicInvoke()); //Works fine
//obj = null; //Now, obj is set to null, the TestObject("Hello 1") can be collected by GC
GC.Collect(); //Force GC
//Console.WriteLine("Is obj null: " + ((obj) == null ? "True" : "False"));
Console.WriteLine("After GC collection: " + ((Delegate)list[0].Target).DynamicInvoke());
Console.ReadKey();
}

关于c# - 当 WeakReference 引用委托(delegate)时 GC 不收集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14007569/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com