Managed Extensions: Using Delegates and Events

Wednesday Aug 4th 2004 by Tom Archer

Tom Archer presents a step-by-step tutorial on understanding and using .NET delegates and events from the C++ Managed Extensions.

Despite the many available tutorials and examples for using delegates and events in .NET, I continue to receive quite a few questions from people regarding these extremely useful types. Therefore, this week's article presents a step-by-step tutorial for understanding and using delegates and events from the C++ Managed Extensions.

Delegate and Event Overview

.NET programming includes the concept of delegates and events to facilitate the Observer or Publish/Subscribe design pattern. Most times, you use events in much the same manner that callback functions have been used for years in standard Win32 API or MFC programming. The program flow works like this:
  1. An object (the event sender) publishes the fact that it can provide information—such as a user's interaction with the system or data changing—in the form of an event.
  2. The client code (the event receiver) can then subscribe to the desired object's event—by specifying a method to be called when the event is fired or raised—if its program logic needs to be made aware of the published event.
  3. When the event occurs, the client's event handler is invoked.
Also note that the client code can subscribe to multiple events from multiple event senders and at any time can specify that it no longer wishes to be notified of a given event.

Since the event sender shouldn't be coupled with the event receiver (in terms of knowing which object or method will receive the event that will be raised), .NET defines a generic layer (function seam) between the sender and receiver. This layer is defined by a special .NET type (called a Delegate) that provides the functionality of a type-safe function pointer.

Here are the basic steps for subscribing to a .NET event:
  1. Locate the desired class/event
  2. Define the event handler
  3. Subscribe to the event

Locate the Desired Class/Event

Events are always members of a class, so let's look at an example class/event that is already defined in the .NET BCL (Base Class Library): FileSystemWatcher. Because the FileSystemWatcher class' sole objective is to asynchronously monitor the file system for various types of file and directory modifications, it provides events that allow client code to specify which types of modifications of which they need to be made aware. One such event is the FileSystemWatcher::Deleted event that is raised whenever a file or directory in the specified path is deleted from the file system (either programmatically or by a user). Therefore, if your application needed to be made aware of such an activity, it would simply subscribe to this event.

Define the Event Handler

Before you can define the event handler, you need to look at the event declaration. Here's such a declaration in Managed Extension syntax:
// Event sender's declaration of the event
public: __event FileSystemEventHandler* Deleted;
The first thing to notice is the Managed Extensions __event type. This simply tells the .NET runtime that Deleted is an event that client code can subscribe to. The second thing to notice is the type that follows it. This is the Delegate type. Your event handler must conform to the signature of this Delegate. Therefore, you would simply look up the FileSystemEventHandler signature in online-help, where you would see the following:
// Delegate declaration
public __gc __delegate void FileSystemEventHandler(
  Object* sender,
  FileSystemEventArgs* e
Armed with this information, you now know how to define the event handler. As an example of that, here's a method called OnDelete where the return value and parameter list are the same as the FileSystemEventHandler signature:
// Event handler
void OnDeleted (Object* source, FileSystemEventArgs* e)
  // event processing logic here

Subscribe to the Event

At this point, you need only to subscribe to the event. To do that, first instantiate a FileSystemWatcher object. Then, use the Event class's overloaded += operator and add a new instance of a FileSystemEventHandler object, passing it the current object and the event handler (OnDelete) that will be called when the event fires:
// Client code (event receiver)
FileSystemWatcher* pWatcher = new FileSystemWatcher();
pWatcher->Deleted += new FileSystemEventHandler(this, OnDeleted); 

Define Your Own Events and Delegates Too

That's all there is to it: three simple steps to subscribing to any .NET event with your own event handlers. In addition to learning how to use these types (as they will be used more and more in future releases of the BCL), I would also encourage you to start defining your own events and delegates in your code. This enables a generic means of allowing client code to be alerted to application-specific events.

About the Author

The founder of the Archer Consulting Group (ACG), Tom Archer has been the project lead on three award-winning applications and is a best-selling author of 10 programming books as well as countless magazine and online articles.

Mobile Site | Full Site
Copyright 2017 © QuinStreet Inc. All Rights Reserved