2013-05-27 15 views
10

Mam problem z WeakReferences w .NET 4.x biegałam testy, aby upewnić się niektóre obiekty nie zostały odniesione już (za pomocą WeakReferences) i zauważyłem, że zachowanie nie jest zgodne we wszystkich wersjach ramowa:Jak wymusić pełne usuwanie śmieci w .NET 4.x?

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); 
    } 
} 

Wyniki:

.NET 2.0 PASS 
.NET 3.0 FAIL 
.NET 3.5 PASS 
.NET 4.0 FAIL 
.NET 4.5 FAIL 

Czy to udokumentowane gdzieś?

Czy istnieje sposób zmuszenia GC do zebrania tego odwołania w .NET 4.5?

Z góry dziękuję.

+4

Tylko uwaga: GC nie zbiera niedostępnych obiektów w trybie debugowania. – 2kay

+0

Dzięki Wezmę do tego – Guillaume86

+0

Hmm, kod, który pokazałeś działa dla mnie we wszystkich wersjach frameworka. (Cóż, nie mam zainstalowanego NUnit, więc używam 'Debug.Assert', ale to nie powinno zmieniać zachowania). –

Odpowiedz

6

Problem tutaj jest związany z NCrunch. Kod działa poprawnie na moim komputerze dla wszystkich wersji ramach gdybym zastąpić test z prostego połączenia do 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); 
    } 
} 
+0

Dzięki, to NCrunch złożył te instrumenty, wyłączyłem opcję i minęło. – Guillaume86

+0

Próbuję to zrobić, ale moja aplikacja jest zbudowana na Silverlight 4, a ja nie mam opcji WaitForFullGCCuplete. Czy byłby na SL5? –

0

Dzięki @ Cody Grey (patrz komentarze), wymyśliłem to.

Używam NCrunch do uruchamiania moich testów i oprzyrządowania zespołu wyjściowego, wytwarzając to zachowanie (wyłączenie oprzyrządowania wyjściowego sprawiają, że test przechodzi na wszystkich platformach).

Powiązane problemy