Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

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

Moderationshinweis von gfoidl (25.11.2011 - 19:31)

Abgeteilt von Dispose implementieren und verwenden (IDisposable)

TripleX
myCSharp.de - Member

Avatar #avatar-3071.jpg


Dabei seit:
Beiträge: 328
Herkunft: Nürtingen

Themenstarter:

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

beantworten | zitieren | melden

Ich wollte noch folgendes hinzufügen:
Zitat
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
private Nachricht | Beiträge des Benutzers
Golo Roden
myCSharp.de - Member

Avatar #avatar-2167.png


Dabei seit:
Beiträge: 4.207
Herkunft: Riegel am Kaiserstuhl

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
Neals
myCSharp.de - Member



Dabei seit:
Beiträge: 203
Herkunft: Nordseeküste

beantworten | zitieren | melden

Zitat von TripleX
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.
Zitat von Golo Roden
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";
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers