2009-03-03 7 views
2

Ich habe den folgenden Code bekommt:Warum wird mein .net-Destruktor in diesem sehr einfachen Szenario nicht aufgerufen?

public class A 
    { 
     ~A() 
     { 
      Console.WriteLine("destructor"); 
     } 
    } 

public static A Aref; 
static void Main(string[] args) 
    { 
     Aref = new A(); 
     int gen = GC.GetGeneration(Aref); 
     Aref = null; 
     GC.Collect(gen, GCCollectionMode.Forced); 
     Console.WriteLine("GC done"); 

    } 

Ich dachte, meine Finalizer-Methode auf meinen Aufruf an GC.Collect genannt werden würde, was nicht der Fall ist.

Kann mir jemand erklären warum?

Antwort

13

Finalizer werden nicht aufgerufen, bevor GC.Collect() zurückgibt. Die Finalizer werden in einem separaten Thread ausgeführt. Sie können auf sie warten, indem Sie GC.WaitForPendingFinalizers() aufrufen.

6

Der Finalizer wird während der Auflistung in Ihrem Beispiel nicht aufgerufen, da er noch von der finalisierbaren Warteschlange gerootet wird. Es ist jedoch für die Finalisierung geplant, was bedeutet, dass es während der nächsten Speicherbereinigung gesammelt wird.

Wenn Sie sicherstellen möchten, dass Instanzen von Typen mit einem Finalizer gesammelt werden, müssen Sie zwei solcher Sammlungen erstellen.

GC.Collect(); 
GC.WaitForPendingFinalizers(); 
GC.Collect(); 

Aber im Allgemeinen sollten Sie die Collect() Methode nicht selbst anrufen.

+0

Warum ist die zweit benötigt sammeln? – Mark13426

+0

Sammeln aller Objekte, die für die Ausführung ihrer Finalizer geeignet sind. Der a-Typ hat einen Finalizer, die Instanzen werden von der Finalizer-Warteschlange gerootet, bis der Finalizer ausgeführt oder unterdrückt wurde. –

-1

Auch wenn Sie für die GC fragen zu sammeln, ist es nicht sicher, dass dieses spezifische Objekt zerstört wird (da es nicht in der Erzeugung in diesem Moment gesammelt werden könnte)

+0

In diesem einfachen Beispiel stellt das OP sicher, dass die relevante Generation erfasst wird. Wenn also keine Sammlung vor dem expliziten Aufruf von Collect() vorhanden ist, sollte es wie erwartet funktionieren. –

Verwandte Themen