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.
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);
}
}
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).
来源:https://stackoverflow.com/questions/16771249/how-to-force-full-garbage-collection-in-net-4-x