0Pricing
C# Academy · Lektion

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

Schnelltest: Was ist eine häufige Ursache für Speicherlecks bei der Verwendung von C#-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

  1. delegate, Action/Func, Closures
  2. Events: Publish/Subscribe, event-Schlüsselwort
  3. Event-Muster und Fallstricke (Speicherlecks)
← Zurück zu C# Academy