Events are, like delegates, a late binding mechanism. In fact,
events are built on the language support for delegates.
Events are a way for an object to broadcast (to all interested
components in the system) that something has happened. Any other
component can subscribe to the event, and be notified when an event
is raised.
You've probably used events in some of your programming. Many graphical
systems have an event model to report user interaction. These events would
report mouse movement, button presses and similar interactions. That's one
of the most common, but certainly not the only scenario where events are
used.
You can define events that should be raised for your classes. One important
consideration when working with events is that there may not be any
object registered for a particular event. You must write your code so that
it does not raise events when no listeners are configured.
Subscribing to an event also creates a coupling between two objects (the event
source, and the event sink). You need to ensure that the event sink unsubscribes
from the event source when no longer interested in events.
Design goals for event support
The language design for events targets these goals:
Enable very minimal coupling between an event source and an event sink. These two components may not be written by the same organization, and may even be updated on totally different schedules.
It should be very simple to subscribe to an event, and to unsubscribe from that same event.
Event sources should support multiple event subscribers. It should also support having no event subscribers attached.
You can see that the goals for events are very similar to the goals for delegates.
That's why the event language support is built on the delegate language support.
Language support for events
The syntax for defining events, and subscribing or unsubscribing from events is
an extension of the syntax for delegates.
To define an event you use the event keyword:
public event EventHandler<FileListArgs> Progress;
The type of the event (EventHandler<FileListArgs> in this example) must be a
delegate type. There are a number of conventions that you should follow
when declaring an event. Typically, the event delegate type has a void return.
Event declarations should be a verb, or a verb phrase.
Use past tense when
the event reports something that has happened. Use a present tense verb (for
example, Closing) to report something that is about to happen. Often, using
present tense indicates that your class supports some kind of customization
behavior. One of the most common scenarios is to support cancellation. For example,
a Closing event may include an argument that would indicate if the close
operation should continue, or not. Other scenarios may enable callers to modify
behavior by updating properties of the event arguments. You may raise an
event to indicate a proposed next action an algorithm will take. The event
handler may mandate a different action by modifying properties of the event
argument.
When you want to raise the event, you call the event handlers using the delegate invocation
syntax:
Progress?.Invoke(this, new FileListArgs(file));
As discussed in the section on delegates, the ?.
operator makes it easy to ensure that you do not attempt to raise the event
when there are no subscribers to that event.
You subscribe to an event by using the += operator:
The handler method typically has the prefix 'On' followed
by the event name, as shown above.
You unsubscribe using the -= operator:
fileLister.Progress -= onProgress;
It's important that you declare a local variable for the expression that
represents the event handler. That ensures the unsubscribe removes the handler.
If, instead, you used the body of the lambda expression, you are attempting
to remove a handler that has never been attached, which does nothing.
In the next article, you'll learn more about typical event patterns, and
different variations on this example.
The source for this content can be found on GitHub, where you can also create and review issues and pull requests. For more information, see our contributor guide.
.NET feedback
.NET is an open source project. Select a link to provide feedback:
Do you want to know how to add your business logic to existing functionality in Microsoft Dynamics 365 Business Central? In this module, you'll learn how to add code and work with events.