using System.Runtime.CompilerServices;
public static class Program
public static class DelegateKeeper
private static ConditionalWeakTable<object, object> cwtAction = new ConditionalWeakTable<object, object>();
public static void KeepAlive(Action action) => cwtAction.Add(action.Target, new object());
public void DoSomething() { }
public static class GcHelper
public static void Collect()
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
GC.WaitForPendingFinalizers();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
GC.WaitForPendingFinalizers();
static WeakReference<Action> weakRef;
public static void Main()
Console.WriteLine($"weakRef.Target is alive = {weakRef.TryGetTarget(out _)}, expected true because inst keep a hold on SomeClass.");
Console.WriteLine($"weakRef.Target is alive = {weakRef.TryGetTarget(out _)}, expected false, because there is no more ref on SomeClass.");
private static void Proc1Scoped()
var action = inst.DoSomething;
weakRef = new WeakReference<Action>(action);
DelegateKeeper.KeepAlive(action);
private static void Proc2Scoped()