Sie sind auf Seite 1von 25

C# Event Processing

Model

Solving The Mystery

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 its


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

C# Event Processing Macro View


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 its
event handler code

Object A

Object B

(Event Publisher)

(Event Subscriber)

Subscriber List
(Object B)

Object A maintains a
list of subscribers for
each publishable
event

Event Handler Code

Object B subscribes to event


(or events) generated by Object A.

C# Event Processing Macro View


Lets map Object A and Object B to some familiar object types
When a Click event
occurs notification is sent
to all the subscribers on
the list

MainApp processes the


Click notification in its
onButtonClick event
handler code

Button

MainApp

(Event Publisher)

(Event Subscriber)

Subscriber List
(MainApp.onButtonClick)

Button maintains a
list of subscribers of
its
Click event

onButtonClick

MainApp subscribes to Buttons


Click event

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?

Lets 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


(MulticastDelegate) 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 subscribers 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

Youll 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 publishers 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 publishers event.
The event handler methods signature
must match the signature required by
the publishers 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

Das könnte Ihnen auch gefallen