c# event processing model solving the mystery. agenda introduction c# event processing macro view...
TRANSCRIPT
Agenda
Introduction C# Event Processing Macro View Required Components Role of Each Component How To Create Each Type Of
Component
Introduction
C# is a modern programming language supported by an extensive set of API structures and classes. i.e., The .Net Framework
C# supports event-driven programming normally associated with Microsoft Windows applications.
One normally thinks of events as being generated by GUI components …but any object can generate an “event” if it’s
programmed to do so…
C# Event Processing Macro View
Generally speaking, two logical components are required to implement the event processing model: 1) An event producer (or publisher) 2) An event consumer (or subscriber)
Each logical components has assigned responsibilities
Consider the following diagram
Object B(Event Subscriber)
Object A(Event Publisher)
Subscriber List(Object B)
Event Handler Code
Object B subscribes to event (or events) generated by Object A.
Object A maintains a list of subscribers for
each publishable event
When an Event occurs notification is sent to all the subscribers on the list for that particular event…
Object B processes the event notification in itsevent handler code
C# Event Processing Macro View
C# Event Processing Macro View
Let’s map Object A and Object B to some familiar object types…
MainApp(Event Subscriber)
Button(Event Publisher)
Subscriber List(MainApp.onButtonClick)
onButtonClick
MainApp subscribes to Button’s Click event
Button maintains a list of subscribers of
itsClick event
When a Click event occurs notification is sent to all the subscribers on the list…
MainApp processes the Click notification in itsonButtonClick event
handler code
C# Event Processing Macro View
These two diagrams hide a lot of details How is the subscriber list maintained? How is the event generated? How is notification sent to each
subscriber? What is an event – really? How can you add custom event
processing to your programs? This presentation attempts to answer
these questions in a clear manner…
C# Event Processing Macro View
The .Net API contains lots of classes that generate different types of events… Most are GUI related
Can you think of a few?
It also contains lots of Delegates Can you name at least one?
Let’s take a closer look at the C# event processing model
Required Components
To implement custom event processing in your programs you need to understand how to create the following component types: Delegates Event Generating Objects (publishers)
Events Event Notification Methods
Event Handling Objects (subscribers) Event Handler Methods
Required Components
You will also need to know how to pass information related to the event between the event generating object and the subscriber object The EventArgs class can be used as-is or
subclassed The EventArgs class captures generic
information about an object and the event that occured
Role of Each Component- Delegate -
Delegate Delegate types represent references to
methods with a particular parameter list and return type
Example EventHandler(Object sender, EventArgs e) Represents a method that has two parameters,
the first one being of type Object and the second being of type EventArgs. Its return type is void.
Any method, so long as its signature matches that expected by the delegate, can be handled by the delegate.
Role of Each Component- Delegate -
But just what is a delegate? A delegate is a reference type object. A delegate extends either the
System.Delegate or MulticastDelegate class
Depends on whether one (Delegate) or more (MulticaseDelegate) subscribers are involved
You do not extend Delegate or MulticastDelegate
The C# compiler does it for you
Role of Each Component- Delegate -
The delegate object contains the subscriber list. It is actually implemented as a linked list
where each node of the list contains a pointer to a subscriber’s event handler method
Delegates are types – like classes Except – you declare them with the
delegate keyword and specify the types of methods they can reference
Role of Each Component- Publisher -
A publisher is any class that can fire an event and send event notifications to interested subscribers
A publisher class contains the following critical elements: An event field
This is what subscribers subscribe to… An event notification method
This activates the subscriber notification process when the event occurs
And some means of generating the event or recognizing the event in question has occurred
This usually happens in a method as well
Role of Each Component- Event -
An event is a field in a class Events are declared with the event
keyword Events must be a delegate type
Delegates, remember, are objects that contain a list of pointers to subscriber methods that delegate can process
An event field will be null until the first subscriber subscribes to that event You’ll see what I mean by this in a moment
Role of Each Component- Event Notification Method -
In addition to an event field a publisher will have a method whose job it is to start the subscriber notification process when the event in question occurs An event notification method is just a
normal method It usually has a parameter of EventArgs
or a user-defined subtype of EventArgs. But it can have any number and type of
parameters you require
Role of Each Component- Subscriber -
A subscriber is a class that registers its interest in a publisher’s events
A subscriber class contains one or more event handler methods
Role of Each Component- Event Handler Method -
An event handler methods is an ordinary method that is registered with a publisher’s event.
The event handler method’s signature must match the signature required by the publisher’s event delegate.
An Custom Event Example- Elapsed Minute Timer -
This example includes five separate source files: Delegate.cs Publisher.cs Subscriber.cs MinuteEventArgs.cs MainApp.cs
using System;
namespace CustomEventExample {
public delegate void ElapsedMinuteEventHandler(Object sender, MinuteEventArgs e);
} // end CustomEventExample namespace
using System;
namespace CustomEventExample {
public class MinuteEventArgs : EventArgs { private DateTime date_time; public MinuteEventArgs(DateTime date_time){ this.date_time = date_time; } public int Minute { get { return date_time.Minute; } } }}
using System;
namespace CustomEventExample { public class Publisher { public event ElapsedMinuteEventHandler MinuteTick; public Publisher(){ Console.WriteLine("Publisher Created"); } public void countMinutes(){ int current_minute = DateTime.Now.Minute; while(true){ if(current_minute != DateTime.Now.Minute){ Console.WriteLine("Publisher: {0}", DateTime.Now.Minute); onMinuteTick(new MinuteEventArgs(DateTime.Now)); current_minute = DateTime.Now.Minute; }//end if } // end while } // end countMinutes method public void onMinuteTick(MinuteEventArgs e){ if(MinuteTick != null){ MinuteTick(this, e); } }// end onMinuteTick method } // end Publisher class definition} // end CustomEventExample namespace
using System;
namespace CustomEventExample {
public class Subscriber { private Publisher publisher; public Subscriber(Publisher publisher){ this.publisher = publisher; subscribeToPublisher(); Console.WriteLine("Subscriber Created"); } public void subscribeToPublisher(){ publisher.MinuteTick += new ElapsedMinuteEventHandler(minuteTickHandler); } public void minuteTickHandler(Object sender, MinuteEventArgs e){ Console.WriteLine("Subscriber Handler Method: {0}", e.Minute); } } // end Subscriber class definition} // end CustomEventExample namespace
using System;
namespace CustomEventExample {
public class MainApp { public static void Main(){ Console.WriteLine("Custom Events are Cool!"); Publisher p = new Publisher(); Subscriber s = new Subscriber(p); p.countMinutes(); } // end main } //end MainApp class definition} // end CustomEventExample namespace