Reputation: 14400
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.
Upvotes: 10
Views: 7633
Reputation: 244732
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);
}
}
Upvotes: 8
Reputation: 14400
Thanks to @ Cody Gray (see comments), I figured that out.
I use NCrunch to run my tests and it was instrumenting the output assembly, producing this behavior (disabling output instrumenting make the test pass on all platforms).
Upvotes: 0