2017-01-24 1 views
0

Ich habe eine Klasse, die eine Methode zur "Registrierung" von Delegaten verfügbar macht (diese Delegaten werden als Teil eines späteren Prozesses aufgerufen). Der an die Methode übergebene Delegat wird in ein kleines Objekt eingeschlossen, das dann einem Wörterbuch hinzugefügt wird. Das Verfahren sieht ein bisschen wie folgt aus: -Sind diese Delegierten Müll gesammelt?

public void Add(int id, Func<bool> someDelegate) 
{ 
    var wrapper = new MyDelegateWrapper(someDelegate); 
    _wrappers.Add(id, wrapper); // _wrappers is a Dictionary<> 
} 

Einige Zeit später, könnte ich durch den Aufruf einer Methode, wie diese „registrieren de-“ Delegierten entscheiden: -

public void Remove(int id) 
{ 
    _wrappers.Remove(id); 
} 

Ich bin gespannt, wissen, ob dieser Code GC-Probleme einführt. d. h., wird verhindert, dass entweder das "Wrapper" -Objekt oder das Objekt, das den Delegierten erstellt hat, GC'd? Und macht es einen Unterschied, ob die aufrufenden Objekte einen anonymen Delegierten oder eine ihrer eigenen "echten" Methoden übergeben?

+0

Fragen wie diese zu stellen wird nicht auf jede mögliche Situation skalieren. Wenn Sie sich Gedanken über Speicherlecks machen, * profilieren * Sie Ihren Code und sehen Sie, ob Sie tatsächlich Speicherlecks haben. –

+1

Delegierte sind normale .net-Objects, und sie sind GC'd und folgen demselben Lebenszyklus wie jedes andere Objekt. Der von Ihnen bereitgestellte Code führt also zu keinen GC-Problemen. Sowohl Wrapper als auch Delegierte werden gecodiert, wenn kein anderes Objekt sie aufrufen kann. –

Antwort

1

Der GC erfasst alle Objekte, die keine eingehenden Referenzen von Objekten haben, die nicht erfasst werden sollen. Dies wird erreicht, indem ein Objektgraph aus allen Referenzen auf dem Stapel und in statischen Feldern erstellt wird. Wenn ein Objekt eine ausgehende-Referenz auf ein anderes Objekt hat, verhindert das Garbage Collection nicht.

Wenn Sie einem Ereignis einen Handler hinzufügen, wird dadurch ein Verweis vom Objekt, das das Ereignis enthält, auf das Objekt erstellt, das den Ereignislistener enthält. Das verhindert nicht, dass das Objekt mit dem Ereignis erfasst wird.

Die einzige Ausnahme ist, wenn man das Ereignis in Methode Syntax implementieren (das heißt unter Verwendung von addremove und Methoden) und eine Referenz vom Hörer an das Objekt mit den Event-Handler in dem add Verfahren erstellen. Das wäre jedoch sehr ungewöhnlich.

2

Delegaten sind keine COM-Objekte. Sie müssen IDispose nicht implementieren und sind Müll gesammelt, wenn der GC dies für angemessen hält.

Sobald sie von anderen .NET-Objekten nicht mehr erreichbar sind, werden sie für die Sammlung markiert und gesammelt, wenn die CLR Speicherplatz freimachen muss.

Verwandte Themen