English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Gli eventi sono notifiche inviate dagli oggetti per rappresentare l'accadimento di un'operazione. Gli eventi .NET seguono lo stile del pattern Observer.
La classe che genera eventi viene chiamata Publisher (Publisher), la classe che riceve le notifiche è chiamata Subscriber (Subscriber). Un evento può avere più subscriber. Di solito, il Publisher genera un evento quando si verifica una certa operazione. I subscriber che desiderano ricevere notifiche durante l'operazione devono registrarsi per l'evento e gestirlo.
In C#, gli eventi sono delegati encapsulati. Dipendono dal delegato. Il delegato definisce la firma del metodo del gestore di eventi della classe Subscriber.
La seguente figura illustra gli eventi in C#.
Gli eventi sono dichiarati e generati nella classe e associati ai gestori di eventi tramite deleghe della stessa classe o di altre classi. La classe che contiene gli eventi viene utilizzata per pubblicare eventi. Questo viene chiamato Publisher Classe. Altre classi che accettano questo evento sono chiamate classe Subscriber. Gli eventi vengono utilizzati Publisher-Subscriber Modello.
Publisher- È un oggetto che contiene definizioni di eventi e deleghe. La relazione tra eventi e deleghe è anche definita in questo oggetto. Gli oggetti della classe Publisher chiamano questo evento e notificano altri oggetti.
Subscriber- È un oggetto che accetta eventi e fornisce gestori di eventi. Il delegato nel classe publisher chiama il metodo del classe subscriber (gestore dell'evento).
È possibile dichiarare un evento in due passaggi:
Dichiarazione del delegato
Dichiarazione di una variabile delegata utilizzando la parola chiave 'event'
Nell'esempio seguente, viene dimostrato come dichiarare un evento nella classe publisher.
public delegate void Notify(); // delegato public class ProcessBusinessLogic { public event Notify ProcessCompleted; // evento }
Nell'esempio sopra, abbiamo dichiarato un delegato Notify e poi abbiamo dichiarato l'evento ProcessCompleted del tipo delegato Notify nella classe ProcessBusinessLogic utilizzando la parola chiave 'event'. Pertanto, la classe ProcessBusinessLogic è chiamata publisher (pubblicatore). Il delegato Notify specifica la firma del gestore dell'evento ProcessCompleted. Specifica che il metodo del gestore dell'evento dell'oggetto subscriber (abbonato) deve avere il tipo di ritorno void e non avere parametri.
Ora, vediamo come generare l'evento ProcessCompleted. Ecco l'implementazione.
public delegate void Notify(); // delegato public class ProcessBusinessLogic { public event Notify ProcessCompleted; // evento public void StartProcess() { Console.WriteLine("Process Started!"); // Some code here... OnProcessCompleted(); } protected virtual void OnProcessCompleted() // metodo protetto virtuale { // Se ProcessCompleted non è null, chiama il delegato ProcessCompleted?.Invoke(); } }
Sopra, il metodo StartProcess() chiama il metodo onProcessCompleted() alla fine, il che genererà un evento. Di solito, per generare un evento, si dovrebbe utilizzare il metodo protetto e virtuale definito con il nome <EventName>>. La protezione e la virtualizzazione permettono alle classi derivate di sovrascrivere la logica di generazione dell'evento. Tuttavia, le classi derivate dovrebbero sempre chiamare il metodo On<eventName> della classe base per assicurarsi che i delegati registrati ricevano l'evento.
Il metodo OnProcessCompleted() utilizza ProcessCompleted?.Invoke() per chiamare il delegato.
L'oggetto abbonato deve iscriversi all'evento ProcessCompleted e utilizzare il metodo Notify con corrispondenza di firma per gestirlo, come indicato di seguito.
class Program { public static void Main() { ProcessBusinessLogic bl = new ProcessBusinessLogic(); bl.ProcessCompleted += bl_ProcessCompleted; // Iscrizione dell'evento bl.StartProcess(); } // Gestore dell'evento public static void bl_ProcessCompleted() { Console.WriteLine("Processo Completato!"); } }
Sopra, la classe Program è ProcessCompleted I sottoscrittori dell'evento. Utilizza l'operatore += per iscrivere all'evento. Ricorda che questo è lo stesso modo in cui aggiungiamo metodi alla lista di chiamate del delegate multicast. Il metodo bl_processcompleted() gestisce l'evento perché corrisponde alla firma del delegate Notify.
.NET Framework contiene tipi di delegate integrati per eventi comuni, ovvero EventHandler e EventHandler <TEventArgs>. Di solito, qualsiasi evento dovrebbe includere due parametri: la sorgente dell'evento e i dati dell'evento. Per tutti gli eventi che non contengono dati, utilizzare il delegate EventHandler. Per gli eventi che devono inviare dati al gestore, utilizzare il delegate EventHandler<TEventArgs>.
L'esempio mostrato può utilizzare il delegate EventHandler senza dover dichiarare un delegate Notify personalizzato, come segue.
class Program { public static void Main() { ProcessBusinessLogic bl = new ProcessBusinessLogic(); bl.ProcessCompleted += bl_ProcessCompleted; // Event registration bl.StartProcess(); } // Event handling public static void bl_ProcessCompleted(object sender, EventArgs e) { Console.WriteLine("Processo Completato!"); } } public class ProcessBusinessLogic { // Declare the event using the built-in EventHandler public event EventHandler ProcessCompleted; public void StartProcess() { Console.WriteLine("Process Started!"); // Some code here... OnProcessCompleted(EventArgs.Empty); // Nessun dato dell'evento } protected virtual void OnProcessCompleted(EventArgs e) { ProcessCompleted?.Invoke(this, e); } }
Nell'esempio precedente, il metodo event handler bl_ProcessCompleted() contiene due parametri che corrispondono al delegate EventHandler. Allo stesso tempo, viene trasmesso this come mittente e EventArgs. Quando si utilizza Invoke() per sollevare l'evento nel metodo OnProcessCompleted(), è vuoto. Poiché il nostro evento non richiede alcun dato, notifica semplicemente agli abbonati che il processo è stato completato, quindi abbiamo trasmesso EventArgs.Empty.
Molti eventi inviano alcuni dati agli abbonati. La classe EventArgs è la classe base di tutte le classi di dati degli eventi. .NET contiene molte classi di dati degli eventi integrate, come SerialDataReceivedEventArgs. Segue il modello di nomi con EventArgs alla fine di tutte le classi di dati degli eventi. È possibile creare classi di dati degli eventi personalizzati derivando dalla classe EventArgs.
Passare i dati alla funzione di gestione utilizzando EventHandler<TEventArgs> come segue.
class Program { public static void Main() { ProcessBusinessLogic bl = new ProcessBusinessLogic(); bl.ProcessCompleted += bl_ProcessCompleted; // Event registration bl.StartProcess(); } // Event handling public static void bl_ProcessCompleted(object sender, bool IsSuccessful) { Console.WriteLine("Process " + (IsSuccessful ? "Completed Successfully" : "failed")); } } public class ProcessBusinessLogic { // Declare the event using the built-in EventHandler public event EventHandler<bool> ProcessCompleted; public void StartProcess() { try { Console.WriteLine("Process Started!"); // Some code here... OnProcessCompleted(true); } catch(Exception ex) { OnProcessCompleted(false); } } protected virtual void OnProcessCompleted(bool IsSuccessful) { ProcessCompleted?.Invoke(this, IsSuccessful); } }
Nell'esempio sopra, passiamo un singolo valore booleano al gestore per indicare se il processo è stato completato con successo.
Se si desidera passare più valori come dati dell'evento, è possibile creare una classe derivata da EventArgs come segue.
class ProcessEventArgs : EventArgs { public bool IsSuccessful { get; set; } public DateTime CompletionTime { get; set; } }
Esempio: Come passare la classe ProcessEventArgs personalizzata al gestore.
class Program { public static void Main() { ProcessBusinessLogic bl = new ProcessBusinessLogic(); bl.ProcessCompleted += bl_ProcessCompleted; // Event registration bl.StartProcess(); } // Event handling public static void bl_ProcessCompleted(object sender, ProcessEventArgs e) { Console.WriteLine("Process " + (e.IsSuccessful ? "Completed Successfully" : "failed")); Console.WriteLine("Completion Time: " + e.CompletionTime.ToLongDateString()); } } public class ProcessBusinessLogic { // Declare the event using the built-in EventHandler public event EventHandler<ProcessEventArgs> ProcessCompleted; public void StartProcess() { var data = new ProcessEventArgs(); try { Console.WriteLine("Process Started!"); // Some code here... data.IsSuccessful = true; data.CompletionTime = DateTime.Now; OnProcessCompleted(data); } catch(Exception ex) { data.IsSuccessful = false; data.CompletionTime = DateTime.Now; OnProcessCompleted(data); } } protected virtual void OnProcessCompleted(ProcessEventArgs e) { ProcessCompleted?.Invoke(this, e); } }
Therefore, you can create, raise, register, and handle events in C#.
Events are a wrapper around delegates. It depends on the delegate.
Use the 'event' keyword with a delegate type variable to declare an event.
Built-in delegateEventHandler orEventHandler <TEventArgs> is used for common events.
The publisher class raises an event, and the subscriber class registers an event and provides an event handler method.
Il metodo che genera l'evento deve essere chiamato con il nome dell'evento e avere come prefisso “On”.
La firma del metodo dell'handler deve corrispondere alla firma del delegato.
Registra gli eventi utilizzando l'operatore + =. Disdici la sottoscrizione utilizzando l'operatore -=, non utilizzare l'operatore =.
Passa i dati degli eventi utilizzando EventHandler <TEventArgs>.
Deriva la classe base EventArgs per creare una classe di dati personalizzata per eventi.
Gli eventi possono essere dichiarati come statici, virtuali,密封和抽象(static, virtual, sealed, abstract).
L'interfaccia può includere eventi come membri.
Se ci sono più sottoscrittori, l'handler degli eventi viene chiamato in modo sincrono.