Why my weakRef.Target is still alive on the second shot?
Could it be a bug? If not, where is the error?
Result:
weakRef.Target is alive = True, expected true because inst keep a hold on SomeClass.
weakRef.Target is alive = True, expected false, because there is no more ref on SomeClass.
Code:
public static class DelegateKeeper
{
private static ConditionalWeakTable<object, Action> cwtAction = new ConditionalWeakTable<object, Action>();
public static void KeepAlive(Action action) => cwtAction.Add(action.Target, action);
}
public class SomeClass
{
public void DoSomething() { }
}
public static class GcHelper
{
public static void Collect()
{
// OK surely overkill but just to make sure. I will reduce it when everyting will be understood.
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
GC.WaitForPendingFinalizers();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
GC.WaitForPendingFinalizers();
}
}
SomeClass instanceSomeClass;
WeakReference<Action> weakRef;
[TestMethod]
public void TestLifeOfObject()
{
Init();
GcHelper.Collect();
Debug.WriteLine($"weakRef.Target is alive = {weakRef.TryGetTarget(out _)}, expected true because inst keep a hold on SomeClass.");
RemoveLastReferenceOnSomeClass();
GcHelper.Collect();
Debug.WriteLine($"weakRef.Target is alive = {weakRef.TryGetTarget(out _)}, expected false, because there is no more ref on SomeClass.");
}
private void Init()
{
instanceSomeClass = new SomeClass();
var action = instanceSomeClass.DoSomething;
weakRef = new WeakReference<Action>(action);
DelegateKeeper.KeepAlive(action);
}
private void RemoveLastReferenceOnSomeClass()
{
instanceSomeClass = null;
}