The term "event" refers to the occurrence of something interesting, such as a user clicking on a button or choosing an item from a menu. One class notifies other classes when an event occurs.
Terminology:
The publisher determines when the event is raised, and the subscriber determines what action should be taken in response.
There could be multiple subscribers for one event. They will be called in order.
The mechanism for managing this in C# involves delegates. An event is a special kind of multicast delegate that can be invoked only from within the struct or class in which they are defined (the publisher). As a multicast delegate, an event has a list of methods (the handlers) to be called in order.
For instance, we could have a handler that reacts to clicking on a button and another that creates a log entry (this happened and when).
The delegate that handles an event usually has a name ending in "handler".
An event handler will have two arguments: the first is the object which raises the event (usually coded as "this") and the second is an object containing data about what happened. The event handler returns void.
The essential steps are:
In practice, you can think of this in simple terms: "event" means that something significant happens, and "event handler" is a method to be executed when the event occurs, i.e., what to do.
Example adapted from a MSDN page, not involving forms or buttons:
// When this is run, the user presses keys until he/she has pressed "a" // some specific number of times (somewhere up to 10) and then the // event is raised. using System; namespace EventDemo { class Program { static void Main() { int M = 1 + new Random().Next(10); // M is the new threshhold value. Console.WriteLine("The threshold value is {0}", M); Counter c = new Counter(M); // This next line attaches the handler to the event. c.ThresholdReached += c_ThresholdReached; Console.WriteLine("Press the 'a' key to increase the total."); while (Console.ReadKey().KeyChar == 'a') { Console.WriteLine("Adding 1"); c.Add(1); } // This will end when the threshold value is reached and // the event handler calls Exit(). } // This is the event handler. static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e) { Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached); Environment.Exit(0); } } class Counter { private int threshold; private int total; // constructor public Counter(int ThresholdValue) { total = 0; threshold = ThresholdValue; } public void Add(int x) { total += x; if (total >= threshold) { // We now raise the event, in two steps. // We create an object in which to pass data to the handler. ThresholdReachedEventArgs args = new ThresholdReachedEventArgs(); args.Threshold = threshold; args.TimeReached = DateTime.Now; // Next we call a method which calls the handler. OnThresholdReached(args); } } // This method raises the event. protected virtual void OnThresholdReached(ThresholdReachedEventArgs edata) { // EventHandler<T> is a generic delegate class. Here T is the // class used to provide data as the handler's second argument. EventHandler<ThresholdReachedEventArgs> handler = ThresholdReached; if (handler != null) { handler(this, edata); } } // This is the event that will be triggered, also in the Counter class. public event EventHandler<ThresholdReachedEventArgs> ThresholdReached; } // This class contains data to be passed to the handler. // Any such class derives from EventArgs. public class ThresholdReachedEventArgs : EventArgs { public int Threshold { get; set; } // These are auto-implemented. public DateTime TimeReached { get; set; } } }
Random is actually a class representing a pseudo-random number generator, so Random() is a call to its constructor, and Random().Next(10) returns an integer in the range 0 to 9.
EventArgs is a base class for classes that contain event data.
When we use ReadKey, the value returned is actually a struct called ConsoleKeyInfo, and KeyChar is one of its properties.
Environment is a class providing information about and access to various features of the operating environment. One of its methods is Exit(int N) which terminates the process proving an exit code = N. (This works from wherever we are, not necessarily from Main(); the return statement works from Main() only.)
DateTime is a struct dealing with dates and times, and DateTime.Now obtains the current time of day.
When we use Visual Studio, we can create forms and indicate that we want buttons on them. The IDE will automatically create code for an empty event handler for the event of clicking the button. (Here "empty" means it does nothing.)