200 likes | 418 Views
Események C#-ban. Krizsán Zoltán iit 1.0. Mi az?. Aszinkron történésről értesítés egy vagy több objektum számára. Delegátumok segítségével valósítja meg a C#. Lehetőségek. Egy objektum bejelentheti érdeklődését egy esemény iránt
E N D
Események C#-ban Krizsán Zoltán iit 1.0
Mi az? • Aszinkron történésről értesítés egy vagy több objektum számára. • Delegátumok segítségével valósítja meg a C#. Események C#-ban
Lehetőségek • Egy objektum bejelentheti érdeklődését egy esemény iránt • Egy objektum visszavonhatja érdeklődését egy esemény iránt • Egy objektum eseményt definiálhat, amit közzétehet. Események C#-ban
Fax Nyomtató Értesítés az esemény bekövetkezéséről Levelező menedzser Bejelentik érdeklődésüket az esemény iránt Új üzenet érkezik Példa Definiál egy eseményt Események C#-ban
Az eseményt megosztó osztály tervezése IEsemény paramétereinek definiálása • Ha szükségünk van paraméterre.(Sender-t mindenképp megkapja) • Osztály definiálása (neve vége EventArg), őse a Systen.EventArgs • public class StartEventArgs : System.EventArgs {} Események C#-ban
Az eseményt megosztó osztály tervezése IIDelegátum definiálása • Ha van saját esemény paraméter, akkor kell saját delegátum típus is! • Ha nincs, akkor használjuk a System.EventHandler Események C#-ban
Az eseményt megosztó osztály tervezése IIDelegátum definiálása • Ajánlások: • Neve: EventHandler végű • void visszatérés • 2 paraméter: • Első: küldő objektum • Második: paraméterek • Ha nincs + paraméter, akkor használjuk a System.EventHandler-t, aminek a 2. paramétere EventArgs.Empty legyen! Események C#-ban
Az eseményt megosztó osztály tervezése IIIEsemény definiálása • Az előzőleg definiált delegátum a típusa! • Ismernie kell mind a kiterjesztő, mind az érdeklődő osztályoknak! • Láthatósága általában publikus! • Gyakran tulajdonságnak definiáljuk! • Minden esetben a küldő osztály hozza létre. Események C#-ban
Az eseményt megosztó osztály tervezése III (opcionális)Alapértelmezett esemény definiálása • Ha a megosztó osztály komponens • Egy esemény megjelölhető • [System.ComponentModel.DefaultEvent("BeforeStart")] public class Sender : System.ComponentModel.Component{} Események C#-ban
Az eseményt megosztó osztály tervezése IVÉrtesítő fv. definiálása • Protected, virtual a javasolt • Paramétere az esemény paramétere • Neve On-al kezdődik és a vége az esemény neve! • Ellenőrzi, hogy érdeklődik –e valaki az esemény iránt, majd meghívja azokat!protected virtual void OnBeforeStart(StartEventArgs e) { if (BeforeStart != null) BeforeStart(this, e); } Események C#-ban
Az eseményt megosztó osztály tervezése VÉszlelő fv. definiálása • Észleli a várt eseményt • Létrehozza az esemény paraméter osztályát • Meghívja az értesítő fv.-t. Események C#-ban
Példa kódja 1 class MailManager{ public class MailMsgEventArgs : EventArgs { public MailMsgEventArgs( String from, String to, String subject, String body){ this.from =from;this.to = to; this.subject =subject;this.body =body; } public readonly String from, to, subject, body; } public delegate void MailMsgEventHandler(Object sender, MailMsgEventArgs args); public event MailMsgEventHandler MailMsg; protected virtual void OnMailMsg(MailMsgEventArgs e){ if (MailMsg !=null){ MailMsg(this, e); }} public void SimulateArrivingMsg(String from, String to, String subject, String body){ MailMsgEventArgs e = new MailMsgEventArgs(from, to, subject, body); OnMailMsg(e); } } 2 4 3 5 Események C#-ban
Mi is történik? public event MailMsgEventHandler MailMsg; Sor hatására: • Private delegátum adattag (linkelt lista feje) • Publikus add_ tagfv. (System.Delegate.Combine fv.-t hívja) • Publikus remove_ tagfv. (System.Delegate.Remove fv.-t hívja) jön létre. Események C#-ban
Mi is történik? II private MailMsgEventHandler MailMsg = null; [MethodImplAttribute(MethodImplOptions.Synchronized)] public void add_MailMsg(MailMsgEventHandler handler) { MailMsg = (MailMsgEventHandler) Delegate.Combine(MailMsg, handler); } [MethodImplAttribute(MethodImplOptions.Synchronized)] public void remove_MailMsg(MailMsgEventHandler handler) { MailMsg = (MailMsgEventHandler) Delegate.Remove(MailMsg, handler); } Események C#-ban
Az érdeklődő osztály tervezése • Definiáljunk legalább 3 tagfv.-t: • Konstruktort • Eseménykezelő • Érdeklődést visszavonó (unregister) • Konstruktor: • kapja meg a érdekelt eseményt küldő osztályt! • a fv. végén jelentse be érdeklődését az esemény iránt! operator+= Eseménykezelő, ami átfordul xxx.add_ fv. Hívásra. Események C#-ban
Az érdeklődő osztály tervezése II • Eseménykezelő fv.Paraméterszignatúrája meg kell egyezzen az esemény delegátum típusával! • Érdeklődést visszavonó (unregister)operator-= Eseménykezelő, ami átfordul xxx.remove_ fv. Hívásra.Esetleg meghívhatja a Dispose-t is. Események C#-ban
Példa kódja – Fax osztály class Fax{ public Fax(MailManager mm){ mm.MailMsg += new MailManager.MailMsgEventHandler(FaxMsg); } private void FaxMsg(Object Sender, MailManager.MailMsgEventArgs e){ Console.WriteLine("Faxing mail message:"); Console.WriteLine(" To: {0}\n From: {1}\n Subject: {2}\n Body: {3}\n", e.from, e.to, e.subject, e.body); } public void Unregister(MailManager mm){ MailManager.MailMsgEventHandler callback = new MailManager.MailMsgEventHandler(FaxMsg); mm.MailMsg -= callback; } } Események C#-ban
Példa kódja – Pager osztály class Pager{ public Pager(MailManager mm) { mm.MailMsg += new MailManager.MailMsgEventHandler(PagerMsg); } private void PagerMsg(Object Sender, MailManager.MailMsgEventArgs e){ Console.WriteLine("Pager message:"); Console.WriteLine(" To: {0}\n From: {1}\n Subject: {2}\n Body: {3}\n", e.from, e.to, e.subject, e.body); } public void Unregister(MailManager mm) { MailManager.MailMsgEventHandler callback = new MailManager.MailMsgEventHandler(PagerMsg); mm.MailMsg -= callback; } } Események C#-ban
Esemény regisztráció feletti közvetlen felügyelet • A generált kód nem ideális! • Ha nincs párhuzamosság, akkor felesleges a[MethodImplAttribute(MethodImplOptions.Synchronized)]attribútum, ami lassít! • Pláne ha még loggolni is kell! Események C#-ban
Példakód változása class MailManager { public class MailMsgEventArgs : EventArgs{…} public delegate void MailMsgEventHandler(Object sender, MailMsgEventArgs args); private MailMsgEventHandler mailMsgEventHandlerDelegate; public event MailMsgEventHandler MailMsg{ add { mailMsgEventHandlerDelegate = (MailMsgEventHandler) Delegate.Combine(mailMsgEventHandlerDelegate,value); } remove{ mailMsgEventHandlerDelegate = (MailMsgEventHandler) Delegate.Remove(mailMsgEventHandlerDelegate,value); } } protected virtual void OnMailMsg(MailMsgEventArgs e) { if (mailMsgEventHandlerDelegate !=null){ mailMsgEventHandlerDelegate(this, e); } } public void SimulateArrivingMsg(String from,String to,String subject,String body){…} } Események C#-ban