Events are a way to allow a class to send a signal indicating that an event of some importance has taken place. Events are most commonly used in the Windows Forms user interface, sending signals indicating that the user has clicked on a button, typed characters, moved the mouse, or any number of other events.
Events can also be used to indicate other important events that don't have anything to do with a user interface, such as indicating that an object's internal state has changed, that data in a list has changed, and so on.
Events are created from delegates using the event keyword. First, you declare the delegate:
delegate void StateChangedDelegate(object state);
Then you declare the event as a member of a class:
public event StateChangedDelegate OnStateChanged;
Finally, the class interested in the event can subscribe to the event in a syntax that should look familiar to you given your recent exposure to multicast delegates:
otherClass.OnStateChanged += new StateChangedDelegate(OtherClass_StateChanged);
Now the subscribing class will be notified every time the other class's state changes.
The sample in Listing 9.4 shows a class called LongTask. This class has a method called PerformTask. This method simulates a long-running process. The class exposes an event called OnProgress that allows a subscribing class to be notified when progress on the long-running task has been made. This example also makes use of event arguments to show good design patterns that will look very familiar to you when you start working with Windows Forms.
Listing 9.4. Event Publishing and Subscribing Sample
When you run the preceding code, you will see 100 lines of text, each one reporting that another percentage point of work has been completed on the simulated long-running task.
One point about event-based programming that can't be stressed enough is that by using events, you allow a loose coupling of classes and maximize your code reuse.
A bad way to create the code in Listing 9.3 would be to write the code that performs the task directly in a Windows Form so that the code could interact directly with the user interface to indicate progress made by possibly changing the properties of a ProgressBar control. The problem that arises from that design is that the long-running task can then never be used anywhere but within that one form. If you want to perform that same task in a Web Service, a console application, a Windows Service, or even in another Windows Forms application, you will have to cut and paste code and perform some tedious tasks to get it to work.
By using events, you can then have one piece of code that is responsible for performing the task, and you could have the user interface environment subscribe to the progress event. This loose coupling allows you to reuse your code without any modification in any GUI environment.