Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Ereignisse in .NET basieren auf dem Delegatmodell. Das Delegatmodell folgt dem Beobachterentwurfsmuster, mit dem sich ein Abonnent bei einem Anbieter registrieren und Benachrichtigungen empfangen kann. Ein Ereignissender überträgt eine Benachrichtigung, wenn ein Ereignis auftritt. Ein Ereignisempfänger definiert die Antwort. In diesem Artikel werden die Hauptkomponenten des Delegatmodells, das Verwenden von Ereignissen in Anwendungen und das Implementieren von Ereignissen im Code beschrieben.
Auslösen von Ereignissen mit einem Ereignissender
Ein Ereignis ist eine Nachricht, die von einem Objekt gesendet wird, um das Auftreten einer Aktion zu signalisieren. Die Aktion kann eine Benutzerinteraktion sein, z. B. ein Drücken einer Schaltfläche, oder sie kann aus einer anderen Programmlogik resultieren, z. B. einer Eigenschaftswertänderung. Das Objekt, das das Ereignis auslöst, wird als Ereignissender bezeichnet. Der Ereignissender kennt nicht das Objekt oder die Methode, das die ausgelösten Ereignisse empfängt (behandelt). Das Ereignis ist in der Regel ein Member des Ereignissenders. Beispielsweise ist das Click Ereignis ein Mitglied der Button Klasse, und das PropertyChanged Ereignis ist ein Mitglied der Klasse, die die INotifyPropertyChanged Schnittstelle implementiert.
Um ein Ereignis zu definieren, verwenden Sie das C#- Ereignis oder das Visual Basic Event-Schlüsselwort in der Signatur Ihrer Ereignisklasse, und geben Sie den Typ des Delegaten für das Ereignis an. Stellvertretungen werden im nächsten Abschnitt beschrieben.
Zum Auslösen eines Ereignisses fügen Sie in der Regel eine Methode hinzu, die als protected
und virtual
(in C#) oder Overridable
Protected
(in Visual Basic) markiert ist. Die Benennungskonvention für die Methode lautet On<EventName>
, z. B OnDataReceived
. . Die Methode sollte einen Parameter verwenden, der ein Ereignisdatenobjekt angibt, bei dem es sich um ein Objekt vom Typ EventArgs oder einen abgeleiteten Typ handelt. Sie stellen diese Methode bereit, damit abgeleitete Klassen die Logik zum Auslösen des Ereignisses überschreiben können. Eine abgeleitete Klasse sollte immer die On<EventName>
Methode der Basisklasse aufrufen, um sicherzustellen, dass registrierte Stellvertretungen das Ereignis empfangen.
Das folgende Beispiel zeigt, wie ein Ereignis mit dem Namen deklariert ThresholdReached
wird. Das Ereignis wird dem EventHandler-Delegaten zugeordnet, und es wird in einer Methode namens OnThresholdReached
ausgelöst:
class Counter
{
public event EventHandler ThresholdReached;
protected virtual void OnThresholdReached(EventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// provide remaining implementation for the class
}
Public Class Counter
Public Event ThresholdReached As EventHandler
Protected Overridable Sub OnThresholdReached(e As EventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' provide remaining implementation for the class
End Class
Deklarieren von Delegatensignaturen für Ereignishandler
Ein Delegat ist ein Typ, der einen Verweis auf eine Methode enthält. Ein Delegat wird mit einer Signatur deklariert, die den Rückgabetyp und die Parameter für die Methoden anzeigt, die er referenziert. Sie kann Verweise nur auf Methoden enthalten, die ihrer Signatur entsprechen. Ein Delegat entspricht insofern einem typsicheren Funktionszeiger oder einem Rückruf. Eine Delegatdeklaration reicht aus, um eine Delegatklasse zu definieren.
Stellvertretungen haben viele Verwendungsmöglichkeiten in .NET. Im Kontext von Ereignissen ist ein Delegat ein zwischengeschalteter (oder zeigerähnlicher Mechanismus) zwischen der Ereignisquelle und dem Code, der das Ereignis verarbeitet. Sie ordnen einen Delegaten einem Ereignis zu, indem Sie den Delegattyp in die Ereignisdeklaration einschließen, wie im Beispiel im vorherigen Abschnitt gezeigt. Weitere Informationen zu Stellvertretungen finden Sie in der Delegate Klasse.
.NET stellt die Delegaten EventHandler und EventHandler<TEventArgs> bereit, um die meisten Ereignisszenarien zu unterstützen. Verwenden Sie den EventHandler Delegate für alle Ereignisse, die keine Ereignisdaten umfassen. Verwenden Sie den EventHandler<TEventArgs>-Delegaten für Ereignisse, die Daten über das Ereignis enthalten. Diese Delegaten verfügen über keinen Rückgabetypwert und akzeptieren zwei Parameter (ein Objekt für die Ereignisquelle sowie ein Objekt für Ereignisdaten).
Delegaten sind Multicast-Klassenobjekte, was bedeutet, dass sie Verweise auf mehr als eine Ereignisbehandlungsmethode enthalten können. Weitere Informationen finden Sie auf der Delegate Referenzseite. Delegaten bieten Flexibilität und eine genaue Steuerung bei der Ereignisbehandlung. Ein Delegat fungiert als ein Ereignisverteiler für die Klasse, die das Ereignis auslöst, indem er eine Liste der registrierten Ereignishandler für das Ereignis verwaltet.
Verwenden Sie die Delegattypen EventHandler und EventHandler<TEventArgs>, um den erforderlichen Delegat zu definieren. Sie markieren einen Delegaten mit dem delegate
Typ in C# oder dem Delegate
Typ in Visual Basic in der Deklaration. Das folgende Beispiel zeigt, wie sie einen Delegat mit dem Namen ThresholdReachedEventHandler
deklarieren:
public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);
Public Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs)
Arbeiten mit Ereignisdatenklassen
Daten, die einem Ereignis zugeordnet sind, können über eine Ereignisdatenklasse bereitgestellt werden. .NET stellt viele Ereignisdatenklassen bereit, die Sie in Ihren Anwendungen verwenden können. Zum Beispiel ist die SerialDataReceivedEventArgs-Klasse die Ereignisdatenklasse für das SerialPort.DataReceived-Ereignis. .NET folgt einem Benennungsmuster, bei dem alle Ereignisdatenklassen mit dem EventArgs
Suffix enden. Sie bestimmen, welche Ereignisdatenklasse einem Ereignis zugeordnet ist, indem Sie sich den Delegaten für das Ereignis ansehen. Beispielsweise enthält der SerialDataReceivedEventHandler Delegat die SerialDataReceivedEventArgs Klasse als Parameter.
Die EventArgs Klasse ist in der Regel der Basistyp für Ereignisdatenklassen. Sie verwenden diese Klasse auch, wenn einem Ereignis keine Daten zugeordnet sind. Wenn Sie ein Ereignis erstellen, das Abonnenten benachrichtigt, dass etwas passiert ist, ohne dass zusätzliche Daten vorhanden sind, fügen Sie die EventArgs Klasse als zweiten Parameter in den Delegat ein. Sie können den EventArgs.Empty Wert übergeben, wenn keine Daten bereitgestellt werden. Der Delegat EventHandler enthält die EventArgs Klasse als Parameter.
Sie können eine Klasse erstellen, die von der EventArgs Klasse abgeleitet wird, um alle Member bereitzustellen, die zum Übergeben von Daten im Zusammenhang mit dem Ereignis erforderlich sind. In der Regel sollten Sie dasselbe Benennungsmuster wie .NET verwenden und den Namen der Ereignisdatenklasse mit dem EventArgs
Suffix beenden.
Das folgende Beispiel zeigt eine Ereignisdatenklasse mit dem Namen ThresholdReachedEventArgs
, die Eigenschaften enthält, die für das ausgelöste Ereignis spezifisch sind:
public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}
Public Class ThresholdReachedEventArgs
Inherits EventArgs
Public Property Threshold As Integer
Public Property TimeReached As DateTime
End Class
Reagieren auf Ereignisse mit Handlern
Um auf ein Ereignis zu reagieren, definieren Sie eine Ereignishandlermethode im Ereignisempfänger. Diese Methode muss mit der Signatur des Delegaten für das Ereignis übereinstimmen, das Sie behandeln. Im Ereignishandler führen Sie die Aktionen aus, die erforderlich sind, wenn das Ereignis ausgelöst wird, z. B. das Sammeln von Benutzereingaben, nachdem der Benutzer eine Schaltfläche drückt. Um Benachrichtigungen zu empfangen, wenn das Ereignis auftritt, muss die Ereignishandlermethode das Ereignis abonnieren.
Das folgende Beispiel zeigt eine Ereignishandlermethode mit dem Namen c_ThresholdReached
, die der Signatur für den EventHandler Delegaten entspricht. Die Methode abonniert das ThresholdReached
Ereignis:
class ProgramTwo
{
static void Main()
{
var c = new Counter();
c.ThresholdReached += c_ThresholdReached;
// provide remaining implementation for the class
}
static void c_ThresholdReached(object sender, EventArgs e)
{
Console.WriteLine("The threshold was reached.");
}
}
Module Module1
Sub Main()
Dim c As New Counter()
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' provide remaining implementation for the class
End Sub
Sub c_ThresholdReached(sender As Object, e As EventArgs)
Console.WriteLine("The threshold was reached.")
End Sub
End Module
Verwenden statischer und dynamischer Ereignishandler
.NET ermöglicht Es Abonnenten, sich entweder statisch oder dynamisch für Ereignisbenachrichtigungen zu registrieren. Statische Ereignishandler sind für die gesamte Lebensdauer der Klasse wirksam, deren Ereignisse behandelt werden. Dynamische Ereignishandler werden während der Programmausführung explizit aktiviert und deaktiviert, in der Regel als Reaktion auf eine bedingte Programmlogik. Sie können dynamische Handler verwenden, wenn Ereignisbenachrichtigungen nur unter bestimmten Bedingungen benötigt werden, oder wenn Laufzeitbedingungen den spezifischen zu aufrufenden Handler bestimmen. Das Beispiel im vorherigen Abschnitt zeigt, wie Ein Ereignishandler dynamisch hinzugefügt wird. Weitere Informationen finden Sie unter Ereignisse (in Visual Basic) und Ereignissen (in C#).
Auslösen mehrerer Ereignisse
Wenn Ihre Klasse mehrere Ereignisse auslöst, generiert der Compiler ein Feld pro Ereignisdelegatinstanz. Ist die Anzahl der Ereignisse sehr hoch, wird u. U. zu viel Speicher beansprucht, wenn für jeden Delegaten ein Feld generiert wird. In diesen Szenarien stellt .NET Ereigniseigenschaften bereit, die Sie mit einer anderen Datenstruktur Ihrer Wahl zum Speichern von Ereignisdelegaten verwenden können.
Ereigniseigenschaften bestehen aus Ereignisdeklarationen, die von Ereignisaccessoren begleitet werden. Ereignisaccessoren sind Methoden, die Sie zum Hinzufügen oder Entfernen von Ereignisdelegatinstanzen aus der Speicherdatenstruktur definieren.
Hinweis
Ereigniseigenschaften sind langsamer als Ereignisfelder, da jeder Ereignisdelegat abgerufen werden muss, bevor er aufgerufen werden kann.
Der Kompromiss liegt zwischen Arbeitsspeicher und Geschwindigkeit. Wenn Ihre Klasse viele Ereignisse definiert, die selten ausgelöst werden, sollten Sie Ereigniseigenschaften implementieren. Weitere Informationen finden Sie unter Behandeln mehrerer Ereignisse mithilfe von Ereigniseigenschaften.
Erkunden verwandter Aufgaben
Die folgenden Ressourcen beschreiben andere Aufgaben und Konzepte im Zusammenhang mit der Arbeit mit Ereignissen:
- Auslösen und Verarbeiten von Ereignissen: Hier finden Sie Beispiele für das Auslösen und Verarbeiten von Ereignissen.
- Behandeln mehrerer Ereignisse mit Ereigniseigenschaften: Erfahren Sie, wie Sie Ereigniseigenschaften verwenden, um mehrere Ereignisse zu behandeln.
- Erkunden Sie das Designmuster des Beobachters: Überprüfen Sie ein Entwurfsmuster, mit dem ein Abonnent sich bei einem Anbieter registrieren und Benachrichtigungen empfangen kann.
Spezifikationsreferenz überprüfen
Spezifikationsreferenzdokumentation ist für die APIs verfügbar, die die Ereignisbehandlung unterstützen:
API-Name | API-Typ | Referenz |
---|---|---|
EventHandler | Delegieren | EventHandler |
EventHandler<TEventArgs> | Delegieren | EventHandler<TEventArgs> |
EventArgs | Klasse | EventArgs |
Delegieren | Klasse | Delegate |