Visual Studio 2010!

Read now >

View Now
DevSource RSS FEEDS
XML Want an easy way to keep up with breaking tech news? And the Get DevSource headlines delivered to your desktop with RSS.
ADVERTISEMENT
ADVERTISEMENT

 

DevSource.com: Your Source for Visual Studio on Facebook
ADVERTISEMENT
Event Properties in C#
By Jim Mischel

Rate This Article: Add This Article To:

Event Properties in C# - ' Conserving Memory '
( Page 3 of 3 )

Conserving Memory with Event Properties

In order to save memory in a class that has many seldom-used events, you can define a collection class to hold the delegates that are defined. Then, rather than creating event delegates as described above, you create event properties that add and remove event handler delegates to the collection. Events are accessed in the collection by a key, which you define when you add a new event.

The .NET Framework defines a collection, System.ComponentModel. EventHandlerList, which is designed to store event handlers and efficiently retrieve them when an event is raised. Consider the following code, which implements the AlarmClock class using event properties:


public class AlarmClock 
{
    // Create the collection to hold event handlers.
    protected EventHandlerList listEvents = new EventHandlerList();

    // Define the Alarm event key
    static readonly object alarmEventKey = new object();

    //  Define the Alarm event property
    public event AlarmEventHandler Alarm
    {
        add { listEvents.AddHandler(alarmEventKey, value); }
        remove { listEvents.RemoveHandler(alarmEventKey, value); }
    }

    protected virtual void OnAlarm(AlarmEventArgs e)
    {
        // Get the delegate from the events list, and dispatch.
        AlarmEventHandler alarm = (AlarmEventHandler)listEvents[alarmEventKey];
        if (alarm != null)
            alarm(this, e);
    }
}

There are few differences between this code and the previous, "normal" event handling code. Rather than a per-instance Alarm event delegate, we have a static alarmEventKey and the per-class Alarm event property. And, of course, we've added the listEvents collection of type EventHandlerList to hold the event delegates. The other difference is in the way events are dispatched. Rather than accessing the Alarm property, the code obtains the delegate from the listEvents collection. The EventHandlerList accessor function will return a null reference if the requested key does not have an associated delegate.

To add another event to the class, you need to define the EventArgs descendent class and the new delegate type. Then, you add a static key for the new event, create the event property, and add new OnEvent protected method to dispatch the event.

Considerations

The use of event properties isn't free. There is a small amount of memory overhead in creating the events list collection, whether you use EventHandlerList or some other collection class. It makes no sense to implement event properties for classes that have just a handful of events, as there will be little to no memory savings.

Event properties are slightly slower than event fields when it comes to dispatching. With an event field, all the dispatching code must do is examine the field to see if it's null before dispatching. With event properties, your code incurs the runtime overhead of searching the collection of event delegates for the key in order to retrieve the required delegate. The runtime overhead is small, as EventHandlerList is reasonably efficient. In most cases, the runtime penalty is not noticeable.

The trade-off is between memory and speed. Event properties are ideal in situations where you have many events that are infrequently raised. Windows Forms Controls and ASP.NET server controls both use event properties in order to conserve memory.

One very nice thing about event properties is they are an implementation detail. From the outside--that is, the public interface--clients cannot tell if you have implemented your events as fields or properties. Because the use of event properties is transparent, you can change your implementation without affecting how clients use your class.

You can use a hybrid approach, implementing event fields for frequently used events that must operate at the highest possible performance, and event properties for all other events in your class. Mixing event handling models will have no effect on the public interface to your class. Clients access your events the same way, regardless of how they're implemented. However, mixing event handling models in your class can create some confusion among those developers who have to work on your class internals. You should think very carefully before deciding on such a hybrid approach.

You do not have to implement your delegates list with EventHandlerList. You can, if you like, implement your own collection if you find that EventHandlerList does not meet your needs. For example, you might want to create a HashTable or derive a custom class from DictionaryBase. Because the implementation is strictly inside your class and not visible to the outside, the choice is yours.

Although not often required for user code, event properties can be a very useful tool for saving memory in classes that have many infrequently used events. Consider using them if you find that your event handlers are occupying excessive amounts of memory.



 
 
>>> More Using Microsoft Visual Studio Articles          >>> More By Jim Mischel