NGWS SDK Documentation  

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Events and Delegates

An event is a message sent by an object to signal the occurrence of an "action". The action could be caused by user interaction, such as a mouse click, or it could be triggered by some other program logic. The object that raises (triggers) the event is called the event source, and the object that responds to the event is called the event receiver. The problem in event communication is that an event source does not know which object will want to receive the event, and an event receiver does not know where the event may originate. What is needed is an intermediary that will act as a messenger between the source and the receiver. The event model does just that, it uses classes called delegates to mediate event transmission.

What is a delegate? In the NGWS runtime and frameworks, a delegate is a class that can hold a reference to a method. Unlike other classes, a delegate class has a signature, and it can hold references only to methods that match its signature. A delegate is thus equivalent to a type-safe function pointer or a callback. Delegates have other uses besides event handling, but the discussion here will focus on the event functionality of delegates. A delegate class used as an event intermediary is called an event handler, because it holds references to methods that perform event handling logic. A declaration for an event delegate is shown below.

[C#]
//AlarmEventArgs is the class that holds event data for the alarm event.
//A class that holds event data derives form the base class for events,
//EventArgs.
//
public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);

Event delegates have two parameters, the source that raised the event, and the data for the event. All event delegates are multicast, which means that they can hold references to more than one event handling method. This means that an event raised by one source can be dispatched to more that one receiver.

Note A delegate declaration is sufficient to define a delegate class. The declaration provides the signature of the delegate, and the implementation is provided by the NGWS runtime.

Delegates allow for flexibility and fine-grain control in event handling. A delegate acts as an event dispatcher for the class that raises the event by maintaining a list of registered event handlers for the event. To register as a receiver, a class must have an event handling method that matches the signature of the delegate. The class WakeMeUp below has a method AlarmRang that handles the alarm event.

[C#]
public class WakeMeUp {
// AlarmRang has the same signature as AlarmEventHandler
public void AlarmRang(object sender, AlarmEventArgs e){...};
...
}

To register an instance of WakeMeUp as a receiver of the alarm event:

  1. An AlarmEventHandler delegate must refer to it.
  2. The delegate must be registered with an alarm event source

Step 1 is accomplished by creating an instance of the AlarmEventHandler delegate that takes a reference to the AlarmRang method of the WakeUp instance in its constructor, as shown below.

[C#]
//Create instance of WakeMeUp
//
WakeMeUp w = new WakeMeUp();

//Instantiate the event delegate.
//The C# compiler provides a constructor for event handlers that takes 
//only one parameter, the reference to the method that performs the 
//event handling logic. The two parameter constructor for EventHandler
// provided in the class library is to be used by those who
// develop compilers and other tools that target the NGWS runtime.
//
AlarmEventHandler alhandler = new AlarmEventHandler(w.AlarmRang);

Now, whenever alhandler is called, it in turn calls the AlarmRang method of w.

Step 2, registering the delegate with the event source, is illustrated in the Event Delegate Mini-Sample.

Custom event delegates are needed only when the event generates event data. Many events, including some user interface events, do not generate event data. In such situations, the event delegate provided in the class library for the no-data event, System.EventHandler, is adequate. Its declaration is given below

[C#]
// EventArgs is the base class for event data. It does not have
// any data, and hence can be used as the event data class for events
// that do not generate data.
//
delegate void EventHandler(object sender, EventArgs e);

For details on using delegates to provide event functionality in your component or control, see Providing Event Functionality.