Как заставить полную сборку мусора в .NET 4.x?
У меня проблема с WeakReferences в .NET 4.x,
Я запускал тесты, чтобы убедиться, что некоторые объекты больше не ссылаются (используя WeakReferences), и я заметил, что поведение не является согласованным между версиями каркаса:
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);
}
}
Результаты:
.NET 2.0 PASS
.NET 3.0 FAIL
.NET 3.5 PASS
.NET 4.0 FAIL
.NET 4.5 FAIL
Является ли это документированным где-нибудь?
Есть ли способ заставить GC собирать эту ссылку в .NET 4.5?
Спасибо заранее.
Ответы
Ответ 1
Проблема здесь связана с NCrunch. Код отлично работает на моей машине для всех версий фреймворка, если я заменю тест простым вызовом 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);
}
}
Ответ 2
Благодаря @Cody Gray (см. комментарии), я понял это.
Я использую NCrunch для запуска своих тестов, и это инструмент для сборки на выходе, создавая это поведение (отключая выходные инструменты, чтобы пройти тест на всех платформах).