I want to test for object references held improperly and wrote a test that always failed. I simplified the test to the following behaviour:
[Test]
public void ScopesAreNotLeaking()
{
WeakReference weakRef;
Stub scope = null;
using (scope = new Stub())
{
weakRef = new WeakReference(scope);
}
scope = null;
GC.Collect();
GC.WaitForPendingFinalizers();
Assert.That(weakRef.Target, Is.Null);
}
This test however, which does the same without using, passes:
[Test]
public void ScopesAreNotLeaking()
{
WeakReference weakRef;
Stub scope = new Stub();
weakRef = new WeakReference(scope);
scope = null;
GC.Collect();
GC.WaitForPendingFinalizers();
Assert.That(weakRef.Target, Is.Null);
}
The used stub class is simple enough:
class Stub : IDisposable
{
public void Dispose() {}
}
Can someone please explain me that behaviour or – even better – has an idea how to make sure that the object gets garbage collected?
PS: Bear with me if a similar question was asked before. I only examined those questions that have using in the title.
I suspect there may be a local introduced by the using statement. Use ildasm to see if all the references in the function to the object are truly cleared before the call to
GC.Collect. Also try to put the using bit in a separate function that returns the weak reference.