Laden...

MemoryLeaks wegen nicht abgehängter Event-Handler per Dispose vermeiden

Erstellt von TripleX vor 14 Jahren Letzter Beitrag vor 14 Jahren 2.650 Views
Hinweis von gfoidl vor 12 Jahren

Abgeteilt von Dispose implementieren und verwenden (IDisposable)

TripleX Themenstarter:in
328 Beiträge seit 2006
vor 14 Jahren
MemoryLeaks wegen nicht abgehängter Event-Handler per Dispose vermeiden

Ich wollte noch folgendes hinzufügen:

Managed memory leaks are caused by unused objects remaining alive by virtue of unused or forgotten references. A common candidate is event handlers—these hold a reference to the target object (unless the target is a static method).

Zitat aus: C# 4.0 in a Nutshell (O'Reilly)

D.h. wenn man eine Klasse hat, die irgendwelche Event-Handler abboniert hat, sollte man IDisposable implementieren und in der Dispose-Methode den Event-Handler wieder entfernen.

(korrigiert mich falls ich falsch liege - aber so habe ich es verstanden)

MfG TripleX

Träume nicht dein Leben sondern lebe deinen Traum.
Viele Grüße, David Teck

4.207 Beiträge seit 2003
vor 14 Jahren

Zum einen das, zum anderen sollte man im Dispose einer Klasse, die Events anbietet, die angehängten Delegates nullen.

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

N
203 Beiträge seit 2008
vor 14 Jahren

D.h. wenn man eine Klasse hat, die irgendwelche Event-Handler abboniert hat, sollte man IDisposable implementieren und in der Dispose-Methode den Event-Handler wieder entfernen.

Zum einen das, zum anderen sollte man im Dispose einer Klasse, die Events anbietet, die angehängten Delegates nullen.

Um das zu konkretisieren:

EventHandler entfernen wäre...

public MyClass(EventClass eventClass)
{
    eventClass.Click += OnClick;
}

protected virtual void Dispose(bool disposing)
{
    if (disposing)
    {
        eventClass.Click -= OnClick;
    }
}

Und angehängte Delegates nullen wäre...

 public EventHandler<MyEventArgs> MyEvent;

protected virtual void Dispose(bool disposing)
{
    if (dipsosing)
    {
        MyEvent = null;
    }
}

Liege ich da richtig?

[EDIT]Anmerkung von herbivore nachgetragen[/EDIT]

Signatur.Text = "Greetz, Neals";

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo Neals,

ja, aber das darf man nur, wenn disposing true ist. Wenn disposing false ist, darf man nicht mehr auf die verwalteten Ressourcen zugreifen.

herbivore

EDIT 25.11.2011: Genau genommen darf man nur auf die referenzierten Objekte nicht mehr zugreifen, die selbst einen Finalizer haben (und noch genauer nur auf die Teile der Objekte nicht, die durch den Finalizer zerstört oder unzugänglich werden), denn die Reihenfolge des Aufrufs von Finalizern ist nicht garantiert. Auf sonstige verwaltete Ressourcen darf man zugreifen. Auf die Delegaten, die ja keinen Finalizer haben, dürfte man also doch zugreifen. Anderseits braucht man es aber nicht, denn wenn der Finalizer von MyClass aufgerufen wird, dann ist sichergestellt, dass es keine lebende Referenz auf den Delegaten mehr gibt.