2013-05-27 13 views
10

Ho un problema con WeakReferences in 4.x .NET, correvo test per assicurarsi alcuni oggetti non sono state utilizzate più (usando WeakReferences) e ho notato il comportamento non è coerente tra le versioni quadro:Come forzare la garbage collection completa in .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); 
    } 
} 

Risultati:

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

E` la documentati da qualche parte?

C'è un modo per forzare il GC a raccogliere tale riferimento in .NET 4.5?

Grazie in anticipo.

+4

Solo una nota: GC non raccoglie gli oggetti non raggiungibili in modalità debug. – 2kay

+0

Grazie esaminerò il numero – Guillaume86

+0

Hmm, il codice che hai mostrato funziona per me su tutte le versioni del framework. (Beh, non ho installato NUnit, quindi sto usando 'Debug.Assert' ma questo non dovrebbe cambiare il comportamento.) –

risposta

6

Il problema qui è correlato a NCrunch. Il codice funziona bene sulla mia macchina per tutte le versioni del framework se sostituisco la prova con una semplice chiamata al 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

Grazie, NCrunch ha assemblato gli strumenti, ho disattivato l'opzione e l'ho passata. – Guillaume86

+0

Sto cercando di ottenere questo risultato, ma la mia applicazione è basata su Silverlight 4 e non ho l'opzione WaitForFullGCComplete. Sarebbe su SL5? –

0

Grazie a @ Cody Gray (vedi commenti), l'ho capito.

Io uso NCrunch per eseguire i miei test e stava strumentando il gruppo di uscita, producendo questo comportamento (disabilitando lo strumento di output, il test passava su tutte le piattaforme).