Just let me start off with a demonstration:
[TestMethod]
public void Test()
{
var h = new WeakReference(new object());
GC.Collect();
Assert.IsNull(h.Target);
}
This code works as expected. After garbage collection is over, the reference in h
is nullified. Now, here's the twist:
[TestMethod]
public void Test()
{
var h = new WeakReference(new object());
GC.Collect();
try { } // I just add an empty
finally { } // try/finally block
Assert.IsNull(h.Target); // FAIL!
}
I add an empty try/finally block to the test after the GC.Collect()
line and lo, the weakly referenced object is not collected! If the empty try/finally block is added before the GC.Collect()
line, the test passes though.
What gives? Can anyone explain how in exactitude does try/finally blocks affect the lifetime of objects?
Note: all testing done in Debug. In Release both tests pass.
Note 2: To reproduce the app must be targeting either the .NET 4 or the .NET 4.5 runtime and it must be run as 32-bit (either target x86, or Any CPU with "Prefer 32-bit" option checked)