在我看來,當我在對象類的委託方法上使用WeakReference
類時,對象類由GC收集,但仍有另一個副本駐留在WeakReference
中?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
來引用方法TestMethod
在TestObject
。這樣做的目的是當所有硬引用都消失時,GC可以收集到TestObject
。這是我的主要的應用程序看起來像:
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();
}
這是輸出,當我運行上面的代碼:
下面是奇怪的事情。 在第一行,obj
可能會打印"Hello 1"
,因爲它剛剛初始化並且obj
持有對TestObject
的引用。全對了。接下來,obj
被設置爲null
而obj = null
並且GC被迫收集。所以,輸出,obj
的第二行爲true
爲空。最後一行最後一行,由於GC已收集到obj
,我期待它或者拋出NullReferenceException
或者只是在輸出上不打印任何東西。但是,它實際上是在輸出的第一行打印了相同的內容! GC現在應該不會收集TestObject
?!
這引出了一個問題,即在將obj設置爲null後,最初在obj
中保存的TestObject
是否已由GC收集或未收集。
如果我已將整個對象傳遞到WeakReference
即new WeakReference(obj)
而不是委託給WeakReference
,它將完美地工作。
不幸的是,在我的代碼中,我需要將代碼傳遞給WeakReference
。我如何讓WeakReference
正常工作,以便GC可以通過僅引用委託來收集對象?