GC der Delegierten, was fehlt mir? (mein Delegierter wird nicht gesammelt)

8

Ich habe eine Klasse, die sich an einen Delegierten hält, um später etwas zu bewerten.

Sobald ich es ausgewertet habe, indem ich den Delegierten aufrufe, lösche ich den Verweis auf den Delegierten, in der Hoffnung, dass er für die Sammlung infrage kommt. Schließlich könnte es an einer Welt lokaler Variablen festhalten, wenn es als anonyme Methode konstruiert wurde.

Ich habe versucht, einen Komponententest zu erstellen, um dies zu überprüfen, aber es scheint nicht so zu funktionieren, wie ich es geplant habe, stattdessen scheinen meine Annahmen über WeakReference (die ich hier zu Testzwecken verwendet habe), oder eine andere Annahme, hält nicht Wasser.

Sehen Sie sich diesen Code an, den Sie in LINQPad

ausführen können %Vor%

Ich ging davon aus:

  1. Unabhängig von DEBUG Build, Debugger angehängt, da ich den Delegaten in einer separaten Methode erstellt habe, von der ich zurückkomme, sollte nichts an dem Delegaten festhalten, außer den WeakReference und den Lazy<T> Objekten
  2. Wenn ich das Objekt Lazy<T> auffordern, seinen Verweis auf den Delegaten aufzugeben, würde dies die Referenzen auf nur denjenigen reduzieren, den WeakReference an
  3. festhält
  4. Und erzwinge dann eine vollständige Garbage-Collection, wenn man davon ausgeht, dass die einzige Referenz in WeakReference übrig bleibt.
  5. Dann würde der Delegat gesammelt und mein WeakReference würde anzeigen, dass das Objekt nicht mehr lebt

Die Ausgabe des Codes wurde somit erwartet (mit Kommentaren):

%Vor%

Aber stattdessen ist die Ausgabe:

%Vor%

Kann jemand etwas Licht auf das werfen, was ich hier vermisse?

    
Lasse Vågsæther Karlsen 30.11.2011, 12:31
quelle

1 Antwort

6

Das "Problem" ist, dass der Compiler bemerkt, dass er eine einzelne Delegierteninstanz für immer wiederverwenden kann. Es erfasst keinen Kontext, nicht einmal den impliziten Verweis this . Also das:

%Vor%

Wird zu etwas wie:

gemacht %Vor%

Sehen Sie sich den Code in ildasm (oder Reflector ohne aktivierte Optimierung) an, um genau zu sehen, was gerade passiert.

    
Jon Skeet 30.11.2011, 12:36
quelle