I've a problem with WeakReferences in .NET 4.x, I was running tests to make sure some objects were not referenced anymore (using WeakReferences) and I noticed the behavior is not consistent across framework versions:
using System;
using System.Text;
using NUnit.Framework;
[TestFixture]
public class WeakReferenceTests
{
    [Test]
    public void TestWeakReferenceIsDisposed()
    {
        WeakReference weakRef = new WeakReference(new StringBuilder("Hello"));
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.WaitForFullGCComplete();
        GC.Collect();
        var retrievedSb = weakRef.Target as StringBuilder;
        Assert.That(retrievedSb, Is.Null);
    }
}
Results:
.NET 2.0  PASS
.NET 3.0  FAIL
.NET 3.5  PASS
.NET 4.0  FAIL
.NET 4.5  FAIL
Is this documented somewhere?
Is there a way to force the GC to collect that reference in .NET 4.5?
Thanks in advance.
You can force garbage collection either to all the three generations or to a specific generation using the GC. Collect() method. The GC. Collect() method is overloaded -- you can call it without any parameters or even by passing the generation number you would like to the garbage collector to collect.
GC. Collect() Method : Garbage collection can be forced in the system using the GC. Collect() method.
To force a garbage collection, use the hotkey: Ctrl+Alt+Shift+F12, Ctrl+Alt+Shift+F12 (press it twice). If forcing garbage collection reliably makes your scenario work, file a report through the Visual Studio feedback tool as this behavior is likely to be a bug.
The problem here is related to NCrunch. The code works fine on my machine for all versions of the framework if I replace the test with a simple call to Debug.Assert:
using System;
using System.Text;
using System.Diagnostics;
public class WeakReferenceTests
{
    public void TestWeakReferenceIsDisposed()
    {
        WeakReference weakRef = new WeakReference(new StringBuilder("Hello"));
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.WaitForFullGCComplete();
        GC.Collect();
        var retrievedSb = weakRef.Target as StringBuilder;
        Debug.Assert(retrievedSb == null);
    }
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With