C# Ereignis
C#-Ereignisse (Event) sind Member, die verwendet werden, um bestimmte Ereignisbenachrichtigungen an Abonnenten zu senden. Ereignisse werden typischerweise verwendet, um das Beobachter-Muster zu implementieren, das es einem Objekt ermöglicht, andere Objekte über Zustandsänderungen zu informieren, ohne die Details dieser Objekte kennen zu müssen.
EreignisGrundsätzlich handelt es sich um eine Benutzeraktion, wie Tastendrücke, Klicks, Mausbewegungen usw., oder um einige Hinweismeldungen, wie systemgenerierte Benachrichtigungen. Anwendungen müssen auf Ereignisse reagieren, wenn sie auftreten. Zum Beispiel Interrupts.
In C# wird der Ereignismechanismus verwendet, um die Kommunikation zwischen Threads zu implementieren.
Wichtige Punkte:
- Delegat deklarieren: Definiere den Delegattyp, den das Ereignis verwenden wird. Ein Delegat ist eine Funktionssignatur.
- Ereignis deklarieren: Verwenden
eventDas Schlüsselwort deklariert ein Ereignis. - Ereignis auslösen: Das Ereignis zu einem geeigneten Zeitpunkt aufrufen, um alle Abonnenten zu benachrichtigen.
- Abonnieren und Abbestellen von Ereignissen: Andere Klassen können
+=und-=Operatoren verwenden, um Ereignisse zu abonnieren und abzubestellen.
Delegaten über Ereignisse verwenden
Ereignisse werden in einer Klasse deklariert und ausgelöst und sind über Delegaten in derselben Klasse oder in anderen Klassen mit Ereignishandlern verknüpft. Die Klasse, die das Ereignis enthält, wird verwendet, um das Ereignis zu veröffentlichen. Dies wird alsPublisher (Herausgeber)Klassen bezeichnet. Andere Klassen, die dieses Ereignis akzeptieren, werden alsSubscriberKlasse. EreignisverwendungPublish-Subscribe (Publisher-Subscriber)Modell.
Publisher (Herausgeber)Ist ein Objekt, das Ereignis- und Delegatdefinitionen enthält. Die Verbindung zwischen dem Ereignis und dem Delegaten wird ebenfalls in diesem Objekt definiert. Ein Objekt der Publisher-Klasse ruft dieses Ereignis auf und benachrichtigt andere Objekte.
SubscriberIst ein Objekt, das ein Ereignis akzeptiert und einen Ereignishandler bereitstellt. Der Delegat in der Publisher-Klasse ruft Methoden (Ereignishandler) in der Subscriber-Klasse auf.
Ein Ereignis deklarieren (Event)
Um ein Ereignis innerhalb einer Klasse zu deklarieren, müssen Sie zuerst den Delegattyp für das Ereignis deklarieren. Zum Beispiel:
public delegate void BoilerLogHandler(string status);
Dann deklarieren Sie das Ereignis selbst mit demeventSchlüsselwort:
// 基于上面的委托定义事件 public event BoilerLogHandler BoilerEventLog;
Der obige Code definiert einen benanntenBoilerLogHandlerDelegaten und ein benanntesBoilerEventLogEreignis, das den Delegaten aufruft, wenn es ausgelöst wird.
Das folgende Beispiel zeigt, wie man Ereignisse in C# verwendet:
Beispiel
namespace EventDemo
{
// Definieren Sie einen Delegattyp für Ereignishandler
public delegate void NotifyEventHandler(object sender, EventArgs e);
// Publisher-Klasse
public class ProcessBusinessLogic
{
// Ereignis deklarieren
public event NotifyEventHandler ProcessCompleted;
// Methode zum Auslösen des Ereignisses
protected virtual void OnProcessCompleted(EventArgs e)
{
ProcessCompleted?.Invoke(this, e);
}
// Simuliere Geschäftslogikprozess und löse Ereignisse aus
public void StartProcess()
{
Console.WriteLine("Prozess gestartet!");
// Hier können Sie die eigentliche Geschäftslogik hinzufügen
// Geschäftslogik abgeschlossen, Ereignis auslösen
OnProcessCompleted(EventArgs.Empty);
}
}
// Abonnentenklasse
public class EventSubscriber
{
public void Subscribe(ProcessBusinessLogic process)
{
process.ProcessCompleted += Process_ProcessCompleted;
}
private void Process_ProcessCompleted(object sender, EventArgs e)
{
Console.WriteLine("Prozess abgeschlossen!");
}
}
class Program
{
static void Main(string[] args)
{
ProcessBusinessLogic process = new ProcessBusinessLogic();
EventSubscriber subscriber = new EventSubscriber();
// Ereignis abonnieren
subscriber.Subscribe(process);
// Startprozess
process.StartProcess();
Console.ReadLine();
}
}
}
Beschreibung
1. Definieren Sie den Delegattyp:
public delegate void NotifyEventHandler(object sender, EventArgs e);
Dies ist ein Delegattyp, der die Signatur des Ereignishandlers definiert. Normalerweise verwenden SieEventHandleroderEventHandler<TEventArgs>ihn, um einen benutzerdefinierten Delegaten zu ersetzen.
2. Ereignisse deklarieren:
public event NotifyEventHandler ProcessCompleted;
Dies ist ein Ereignis, das den Delegattyp NotifyEventHandler verwendet.
3. Ereignisse auslösen:
protected virtual void OnProcessCompleted(EventArgs e)
{
ProcessCompleted?.Invoke(this, e);
}Dies ist eine geschützte Methode, die verwendet wird, um das Ereignis auszulösen. Verwenden Sie?.InvokeSyntax, um sicherzustellen, dass das Ereignis nur aufgerufen wird, wenn Abonnenten vorhanden sind.
4. Abonnieren und Abbestellen von Ereignissen:
process.ProcessCompleted += Process_ProcessCompleted;
Verwendung durch Abonnenten+=Operator zum Abonnieren eines Ereignisses und Definieren eines EreignishandlersProcess_ProcessCompleted。
Beispiel
Beispiel 1
namespace SimpleEvent
{
using System;
/***********Publisher-Klasse***********/
public class EventTest
{
private int value;
public delegate void NumManipulationHandler();
public event NumManipulationHandler ChangeNum;
protected virtual void OnNumChanged()
{
if ( ChangeNum != null )
{
ChangeNum(); /* Ereignis wird ausgelöst */
}else {
Console.WriteLine( "Ereignis wird nicht ausgelöst" );
Console.ReadKey(); /* Enter drücken, um fortzufahren */
}
}
public EventTest()
{
int n = 5;
SetValue( n );
}
public void SetValue( int n )
{
if ( value != n )
{
value = n;
OnNumChanged();
}
}
}
/***********Subscriber-Klasse***********/
public class subscribEvent
{
public void printf()
{
Console.WriteLine( "Ereignis wird ausgelöst" );
Console.ReadKey(); /* Enter drücken, um fortzufahren */
}
}
/***********Auslösen emit***********/
public class MainClass
{
public static void Main()
{
EventTest e = new EventTest(); /* Objekt instanziieren, Ereignis wird beim ersten Mal nicht ausgelöst */
subscribEvent v = new subscribEvent(); /* Objekt instanziieren */
e.ChangeNum += new EventTest.NumManipulationHandler( v.printf ); /* Registrieren */
e.SetValue( 7 );
e.SetValue( 11 );
}
}
}
Wenn der obige Code kompiliert und ausgeführt wird, liefert er die folgenden Ergebnisse:
event not fire event fire event fire
Dieses Beispiel bietet eine einfache Anwendung zur Fehlersuche an einem Warmwasser-Kesselsystem. Wenn der Wartungsingenieur den Kessel inspiziert, werden die Temperatur und der Druck des Kessels zusammen mit den Anmerkungen des Wartungsingenieurs automatisch in der Protokolldatei aufgezeichnet.
Beispiel 2
using System.IO;
namespace BoilerEventAppl
{
// Boiler-Klasse
class Boiler
{
public int Temp { get; private set; }
public int Pressure { get; private set; }
public Boiler(int temp, int pressure)
{
Temp = temp;
Pressure = pressure;
}
}
// Ereignisherausgeber
class DelegateBoilerEvent
{
public delegate void BoilerLogHandler(string status);
// Ereignis basierend auf dem obigen Delegaten definieren
public event BoilerLogHandler BoilerEventLog;
public void LogProcess()
{
string remarks = "O.K.";
Boiler boiler = new Boiler(100, 12);
int temp = boiler.Temp;
int pressure = boiler.Pressure;
if (temp > 150 || temp < 80 || pressure < 12 || pressure > 15)
{
remarks = "Wartung erforderlich";
}
OnBoilerEventLog($"Protokollierungsinfo:\nTemperatur: {temp}\nDruck: {pressure}\nMeldung: {remarks}");
}
protected void OnBoilerEventLog(string message)
{
BoilerEventLog?.Invoke(message);
}
}
// Diese Klasse speichert die Begriffe zum Schreiben in Protokolldateien
class BoilerInfoLogger : IDisposable
{
private readonly StreamWriter _streamWriter;
public BoilerInfoLogger(string filename)
{
_streamWriter = new StreamWriter(new FileStream(filename, FileMode.Append, FileAccess.Write));
}
public void Logger(string info)
{
_streamWriter.WriteLine(info);
}
public void Dispose()
{
_streamWriter?.Close();
}
}
// Ereignisabonnent
public class RecordBoilerInfo
{
static void Logger(string info)
{
Console.WriteLine(info);
}
static void Main(string[] args)
{
using (BoilerInfoLogger fileLogger = new BoilerInfoLogger("e:\\boiler.txt"))
{
DelegateBoilerEvent boilerEvent = new DelegateBoilerEvent();
boilerEvent.BoilerEventLog += Logger;
boilerEvent.BoilerEventLog += fileLogger.Logger;
boilerEvent.LogProcess();
}
Console.ReadLine();
}
}
}
Wenn der obige Code kompiliert und ausgeführt wird, liefert er die folgenden Ergebnisse:
Logging info: Temperature 100 Pressure 12 Message: O. KWeitere Erweiterungen