Események C#-ban Krizsán Zoltán iit
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#.
Krizsá Krizsán Zoltá Zoltán iit
Esemé Események C#C#-ban
2
Lehetőségek 1.
2.
3.
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.
Krizsá Krizsán Zoltá Zoltán iit
Esemé Események C#C#-ban
3
Példa Fax
Nyomtató
Definiál egy eseményt
Értesítés az esemény bekövetkez éséről
Levelező menedzser Bejelentik érdeklődésüket az esemény iránt Krizsá Krizsán Zoltá Zoltán iit
Új üzenet érkezik
Esemé Események C#C#-ban
4
Az eseményt megosztó osztály tervezése I Esemény paramétereinek definiálása
Osztály definiálása (neve vége EventArg), őse a Systen.EventArgs
Krizsá Krizsán Zoltá Zoltán iit
Esemé Események C#C#-ban
5
Az eseményt megosztó osztály tervezése II Delegá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! Krizsá Krizsán Zoltá Zoltán iit
Esemé Események C#C#-ban
6
Az eseményt megosztó osztály tervezése III Esemé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!
Krizsá Krizsán Zoltá Zoltán iit
Esemé Események C#C#-ban
7
Az eseményt megosztó osztály tervezése IV Értesítő fv. definiálása
Protected, virtual 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!
Krizsá Krizsán Zoltá Zoltán iit
Esemé Események C#C#-ban
8
Az eseményt megosztó osztály tervezése V Észlelő fv. definiálása
1. 2.
3.
Észleli a várt eseményt Létrehozza az esemény paraméter osztályát Meghívja az értesítő fv.-t.
Krizsá Krizsán Zoltá Zoltán iit
Esemé Események C#C#-ban
9
Példa kódja 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); }
Krizsá Krizsán Zoltá Zoltán iit
Esemé Események C#C#-ban
10
Mi is történik? public event MailMsgEventHandler MailMsg; Sor hatására: 1. Private delegátum adattag (linkelt lista feje) 2. Publikus add_ tagfv. (System.Delegate.Combine fv.-t hívja) 3. Publikus remove_ tagfv. (System.Delegate.Remove fv.-t hívja) jön létre.
Krizsá Krizsán Zoltá Zoltán iit
Esemé Események C#C#-ban
11
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); } Krizsá Krizsán Zoltá Zoltán iit
Esemé Események C#C#-ban
12
Az érdeklődő osztály tervezése 1.
Definiáljunk legalább 3 tagfv.-t: • • •
2.
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.
Krizsá Krizsán Zoltá Zoltán iit
Esemé Események C#C#-ban
13
Az érdeklődő osztály tervezése II 3.
4.
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.
Krizsá Krizsán Zoltá Zoltán iit
Esemé Események C#C#-ban
14
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; }
Krizsá Krizsán Zoltá Zoltán iit
Esemé Események C#C#-ban
15
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; }
Krizsá Krizsán Zoltá Zoltán iit
Esemé Események C#C#-ban
16
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(MethodImplOp tions.Synchronized)] attribútum, ami lassít! Pláne ha még loggolni is kell!
Krizsá Krizsán Zoltá Zoltán iit
Esemé Események C#C#-ban
17
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){…} Krizsá } Krizsán Zoltá Zoltán iit
Esemé Események C#C#-ban
18