Event-Muster und Fallstricke (Speicherlecks)
Erkennen und beheben Sie typische Event-Probleme: Melden Sie Handler ab, um Speicherlecks zu vermeiden, speichern Sie Delegate-Referenzen zum Entfernen und verwenden Sie ein IDisposable-Abonnementmuster.
Event-Muster und Fallstricke (Speicherlecks) ist eine kostenlose C# Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 3. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C# Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C# Academy-Kurs umfasst insgesamt 3 Lektionen.
Überblick über Fallstricke
Ziel: Verwenden Sie Events sicher.
- Melden Sie sich ab, um Speicherlecks zu vermeiden.
- Behalten Sie eine Referenz auf denselben Handler, um ihn zu entfernen.
- Bevorzugen Sie ein kleines IDisposable-Muster zur Bereinigung.
- Vermeiden Sie Inline-Handler, die Sie nicht abmelden können.
Abmelden, um Lecks zu vermeiden
Events enthalten Referenzen auf Abonnenten. Wenn der Publisher lange lebt und Sie die Verbindung nie trennen, kann der Abonnent nicht vom Garbage Collector freigegeben werden.
using System;
public class Publisher
{
public event EventHandler Tick;
public void Fire()
{
EventHandler h = Tick;
if (h != null) h(this, EventArgs.Empty);
}
}
public class Subscriber
{
public void Handle(object s, EventArgs e)
{
Console.WriteLine("Handling tick");
}
public void Subscribe(Publisher p) { p.Tick += Handle; }
public void Unsubscribe(Publisher p) { p.Tick -= Handle; } // required to avoid leaks
}
public class Program
{
public static void Main(string[] args)
{
Publisher p = new Publisher();
Subscriber s = new Subscriber();
s.Subscribe(p);
p.Fire(); // prints once
s.Unsubscribe(p); // detach when done
s = null; // now eligible for GC in a real app
p.Fire(); // no output
}
}
Handler-Referenz beibehalten
Um einen anonymen Handler zu entfernen, speichern Sie ihn in einer Variable und übergeben Sie dieselbe Instanz an -=.
using System;
public class Button
{
public event EventHandler Click;
public void Simulate()
{
EventHandler h = Click;
if (h != null) h(this, EventArgs.Empty);
}
}
public class Program
{
public static void Main(string[] args)
{
Button b = new Button();
// BAD: cannot easily remove this later
// b.Click += (s, e) => Console.WriteLine("inline");
// GOOD: store the handler, attach, later detach the same instance
EventHandler saved = (s, e) => Console.WriteLine("saved");
b.Click += saved;
b.Simulate(); // prints "saved"
b.Click -= saved; // can remove because we kept the reference
b.Simulate(); // no output
}
}
Disposable-Anmeldung
Geben Sie von IDisposable ein Objekt aus Subscribe zurück. Verwenden Sie using, um die Anmeldung automatisch aufzuheben.
using System;
public class Ticker
{
public event EventHandler Tick;
public IDisposable Subscribe(EventHandler handler)
{
Tick += handler;
return new Unsubscriber(this, handler);
}
private sealed class Unsubscriber : IDisposable
{
private Ticker _t;
private EventHandler _h;
private bool _done;
public Unsubscriber(Ticker t, EventHandler h) { _t = t; _h = h; }
public void Dispose()
{
if (!_done)
{
_t.Tick -= _h;
_done = true;
}
}
}
public void Fire()
{
EventHandler h = Tick;
if (h != null) h(this, EventArgs.Empty);
}
}
public class Program
{
public static void Main(string[] args)
{
Ticker t = new Ticker();
using (t.Subscribe((s, e) => Console.WriteLine("tick")))
{
t.Fire(); // prints once
}
t.Fire(); // nothing after disposal
}
}
Mit try/finally trennen
Verwenden Sie try/finally, wenn ein Handler auch dann getrennt werden muss, wenn eine Ausnahme ausgelöst wird.
using System;
public class Alarm
{
public event EventHandler Ring;
public void Trigger()
{
EventHandler h = Ring;
if (h != null) h(this, EventArgs.Empty);
}
}
public class Program
{
public static void Main(string[] args)
{
Alarm a = new Alarm();
EventHandler h = (s, e) => Console.WriteLine("ring");
a.Ring += h;
try
{
a.Trigger(); // do work with subscription active
}
finally
{
a.Ring -= h; // always detach
}
a.Trigger(); // no output
}
}
Tipps zur Vermeidung von Lecks
Tipps:
- Abonnenten sollten ihre Abmeldung selbst verwalten (Dispose, finally oder eine explizite Methode).
- Vermeiden Sie die Anmeldung mit Inline-Handlern, die Sie nicht entfernen können.
- Seien Sie bei static events vorsichtig; sie bestehen oft länger als Objekte.
- Halten Sie Handler kurz; blockieren Sie den Publisher nicht.
Ursache von Lecks bei Events
Zusammenfassung
Zusammenfassung: Melden Sie sich ab, um Lecks zu vermeiden, speichern Sie Handler-Referenzen, um sie zu entfernen, und bevorzugen Sie Disposable- oder finally-basierte Bereinigungsmuster für sichere Event-Lebenszyklen.
Häufig gestellte Fragen
Ist die Lektion „Event-Muster und Fallstricke (Speicherlecks)“ kostenlos?
Ja — der vollständige Text von „Event-Muster und Fallstricke (Speicherlecks)“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C# Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C# Academy-Kurs umfasst insgesamt 3 Lektionen.
Was lerne ich in „Event-Muster und Fallstricke (Speicherlecks)“?
Erkennen und beheben Sie typische Event-Probleme: Melden Sie Handler ab, um Speicherlecks zu vermeiden, speichern Sie Delegate-Referenzen zum Entfernen und verwenden Sie ein IDisposable-Abonnementmus… Du übst C# Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um C# Academy zu starten?
Keine Vorkenntnisse erforderlich. C# Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 3.
Wie lange dauert die Lektion „Event-Muster und Fallstricke (Speicherlecks)“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser C# Academy-Lektion Code schreiben und ausführen?
Ja. Jede C# Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- delegate, Action/Func, Closures
- Events: Publish/Subscribe, event-Schlüsselwort
- Event-Muster und Fallstricke (Speicherlecks)