ConditionalWeakTable - GC.Collect() behavior, why it does not operate as expected?

Eric Ouellet 41 Reputation points
2022-10-28T13:29:46.733+00:00

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;  
}  
Developer technologies | Windows Presentation Foundation
Developer technologies | C#
{count} votes

Accepted answer
  1. Viorel 122.6K Reputation points
    2022-10-31T09:23:56.593+00:00

    Try removing the first Debug.WriteLine.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.