CodeGym /Kurse /C# SELF /Subscription auf ein Ereignis und Erstellen von Handlers

Subscription auf ein Ereignis und Erstellen von Handlers

C# SELF
Level 52 , Lektion 2
Verfügbar

1. Syntax der Subscription auf ein Ereignis

Stell dir eine Aufgabenverwaltungs-App vor: wenn eine Aufgabe fertig ist, feuert ein Ereignis und ein Handler kann z.B. eine Benachrichtigung schicken, die UI aktualisieren oder etwas ins Log schreiben. C# macht das Subscriben auf Ereignisse bequem und sicher: du gibst explizit an, welcher konkrete Handler auf welches konkrete Ereignis reagieren soll.

Das Subscriben auf ein Ereignis in C# ist fast so, als würdest du dich in die Gästeliste für eine Party eintragen:

publisher.MyEvent += HandlerMethod;

Hier ist publisher das Objekt, das das Ereignis MyEvent deklariert hat, und HandlerMethod ist die Methode, die aufgerufen wird, wenn dieses Ereignis auftritt.

Schauen wir uns das im Kontext eines minimalen Beispiels an. Angenommen, wir haben eine App zum Zählen von Klicks:

public class Clicker
{
    public event Action Clicked;

    public void Click()
    {
        // Etwas wurde geklickt!
        Clicked?.Invoke();
    }
}

Hier ist unser "Publisher" des Ereignisses Clicked. Jetzt subscript wir einen Handler:

Clicker clicker = new Clicker();

void OnClicked()
{
    Console.WriteLine("Der Knopf wurde gedrückt!");
}

clicker.Clicked += OnClicked;

// Irgendwo im Code
clicker.Click();
// → "Der Knopf wurde gedrückt!"

Wie funktioniert das? Auf das "Klick"-Ereignis haben wir unsere Methode OnClicked gesetzt, und sie wird jedes Mal aufgerufen, wenn ein Klick passiert.

2. Event-Handler: welche es gibt und wie man sie deklariert

Ein Event-Handler ist eine Methode, die aufgerufen wird, wenn ein Ereignis feuert. Seine Signatur muss zum Typ des Delegates des Ereignisses passen. Zum Beispiel, wenn das Ereignis deklariert ist als public event Action Clicked;, dann muss der Handler eine Methode ohne Parameter und ohne Rückgabewert sein.

Handler für Action

void OnClicked() 
{
    Console.WriteLine("Ereignis ist eingetreten (Action)!");
}

Handler für den klassischen EventHandler

Wenn du den klassischen Ansatz mit EventHandler verwendest, nimmt der Handler zwei Parameter: den Sender (object sender) und Event-Daten (EventArgs e):

public class Alarm
{
    public event EventHandler AlarmRaised;

    public void RaiseAlarm()
    {
        AlarmRaised?.Invoke(this, EventArgs.Empty);
    }
}

Alarm alarm = new Alarm();

void AlarmHandler(object sender, EventArgs e)
{
    Console.WriteLine("Der Alarm wurde ausgelöst!");
}

alarm.AlarmRaised += AlarmHandler;
alarm.RaiseAlarm();

Anonymous Methods und Lambda-Ausdrücke

C# erlaubt, anonyme Funktionen und Lambda-Ausdrücke direkt beim Subscriben zu verwenden:

clicker.Clicked += () => Console.WriteLine("Another click!");

Oder etwas komplexer, wenn das Ereignis Argumente hat:

alarm.AlarmRaised += (sender, e) =>
{
    Console.WriteLine($"Alarm raised by: {sender}");
};

4. Nützliche Feinheiten

Subscriben und Unsubscriben: wichtige Feinheiten

Das echte Leben ist, wenn auf der Party zu viele Gäste sind oder jemand nach Hause gehen will. Bei Delegates ist es dasselbe: einen Handler kann man hinzufügen (subscriben) und entfernen (unsubscriben):

// Subscriben
publisher.MyEvent += MyHandler;

// Unsubscriben (wenn der Handler nicht mehr gebraucht wird)
publisher.MyEvent -= MyHandler;

Warum ist das wichtig? Wenn man nicht unsubscribet, speziell in großen Anwendungen, können Handler "hängen bleiben" und den Garbage Collector daran hindern, Objekte freizugeben — daraus resultieren Memory Leaks.

Mehrere Handler

Auf ein Ereignis kannst du beliebig viele Handler subscriben. Sie werden der Reihe nach in der Reihenfolge aufgerufen, in der sie hinzugefügt wurden.

clicker.Clicked += () => Console.WriteLine("Erster Handler!");
clicker.Clicked += () => Console.WriteLine("Zweiter Handler!");

clicker.Click();
// → Erster Handler!
// → Zweiter Handler!

Du kannst Handler sogar "on the fly" subscriben und unsubscriben — das ist flexibel und praktisch.

Warum das wirklich wichtig ist: reale Szenarien

  • UI (Windows Forms, WPF, WinUI, MAUI): Button-Klick, Textänderung in einem Feld — das sind alles Ereignisse.
  • FileSystemWatcher: Benachrichtigung über neue Dateien in einem Ordner.
  • Asynchrone Operationen: Abschluss eines Datei-Downloads, Fortschritt von Tasks.
  • Plugin-System: einzelne Module subscriben auf Ereignisse der Hauptanwendung.

Das Event-Modell ermöglicht es, erweiterbare Architekturen zu bauen: du kannst neue Module hinzufügen und auf existierende Ereignisse subscriben, ohne den Basiskode zu ändern.

Beispiele für Subscriben

Event-Signatur Beispiel für Subscription Beispiel für Handler
event Action
ev += Handler;
void Handler() { ... }
event Action<int>
ev += (x) => { ... };
void Handler(int x) { ... }
event EventHandler
ev += Handler;
void Handler(object s, EventArgs e) { ... }
event EventHandler<CustomArgs>
ev += Handler;
void Handler(object s, CustomArgs e) { ... }

5. Typische Fehler und Fallstricke

Fehler Nr.1: Signaturmismatch des Handlers.
Wenn ein Ereignis als event Action<int> deklariert ist und du versuchst, eine Methode ohne Parameter zu subscriben, wird der Compiler einen Fehler geben. Prüfe immer, dass die Methode zur benötigten Signatur des Ereignisses passt.

Fehler Nr.2: Variable-Capture in Lambdas.
Beim Subscriben mit einem Lambda kann dieses Variablen aus dem umgebenden Scope capturen (vgl. Thema "Closures"). Wenn sich die Variable nach dem Subscriben ändert, sieht der Handler den neuen Wert, was zu unerwartetem Verhalten führen kann.

Fehler Nr.3: Subscriben auf ein nicht initialisiertes Ereignis.
Wenn du dich auf ein Ereignis subscribest, bevor das Objekt, das dieses Ereignis enthält, erstellt und initialisiert ist, riskierst du eine NullReferenceException. Stelle vor dem Subscriben sicher, dass das Objekt bereit ist.

Fehler Nr.4: Mehrfaches Subscriben desselben Handlers.
Wenn derselbe Handler mehrmals auf dasselbe Ereignis subscribet wird, wird er auch so oft aufgerufen. Das ist kein Bug, sondern ein Charakteristikum von Events, aber oft eine unangenehme Überraschung.

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION