Events In C#

Note: Before start reading this article please hold a clear concept on delegates. Follow the link to read the previous article on Delegates.

What is Event?

  1. Event is a way to communicate in-between objects, which send notification to its subscribers (who register for that Event).
  2. Events are declared with an associated delegate.
  3. We know previously that delegate hold a reference to a method.
  4. Events sender send notification that’s how event raised and receiver receive the notifications.
  5. We can extends application by adding new methods without changing existing code.
  6. To build loosely coupled applications.
  7. The class containing the event is used to publish the event, called Publisher/Sender.
  8. Containing information’s about the event known as event arguments.
  9. The class accepts this event is called the Subscriber/Receiver.
  10. The method that execute by publisher call is known as event handlers.

Diagram of Event Sender and Receiver

event

Let’s demonstrate with a sample example:

  1. namespace Events  
  2. {  
  3.     class Program  
  4.     {  
  5.         static void Main(string[] args)  
  6.         {  
  7.             IQTest objTest = new IQTest(); //Publisher  
  8.             NotificationService objNotify = new NotificationService(); //Subscriber  
  9.   
  10.             // += Register a Handler for that Event  
  11.             objTest.ExamStarted += objNotify.OnExamStarted;  
  12.   
  13.             objTest.myExam();  
  14.             Console.Read();  
  15.         }  
  16.     }  
  17.   
  18.     //Publisher or Sender  
  19.     class IQTest  
  20.     {  
  21.         //Delegate  
  22.         public delegate void ExamEventHandler(object source, EventArgs args);  
  23.   
  24.         //Event  
  25.         public event ExamEventHandler ExamStarted;  
  26.   
  27.         public void myExam()  
  28.         {  
  29.             Console.WriteLine("Exam is Starting..");  
  30.             Thread.Sleep(2000);  
  31.             OnExamStarted();  
  32.         }  
  33.   
  34.         //This method will notify the subscriber   
  35.         protected virtual void OnExamStarted()  
  36.         {  
  37.             // Invoke the event  
  38.             if (ExamStarted != null)  
  39.             {  
  40.                 ExamStarted(this, EventArgs.Empty);  
  41.             }  
  42.         }  
  43.     }  
  44.   
  45.     //Subscriber or Receiver  
  46.     class NotificationService  
  47.     {  
  48.         //Handler : That Match Delegate Signature  
  49.         public void OnExamStarted(object source, EventArgs args)  
  50.         {  
  51.             Console.WriteLine("Your time starts now | start answering..");  
  52.         }  
  53.     }  
  54. }  

Output:
Exam is Starting..
Your Time starts now | start answering..

Let’s consider the code step by step:
In this code the publisher is IQTest class, there is a method named OnExamStarted that notifies the attended exam students that the exam is started.

Steps of an Event Sender:
  1. Define a Delegate
  2. Define an event based on that Delegate.
  3. Raise/Publish the event

Point 1: Define a Delegates
As we can see here to define a delegate is similar as method declaration as we saw in the previous article on Delegates.

  1. //Delegate  
  2. public delegate void ExamEventHandler(object source, EventArgs args);  
As we know delegate points a method. Here delegate respond between Publisher/Sender and Subscriber/Receiver. Establish the event handler method.

Point 2: Define an event
  1. //Event  
  2. public event ExamEventHandler ExamStarted;   
An event is declared based on the associated Delegates. 
 
Button click, Text change of a textbox are known as event. Those are generally seen in windows form application.

Point 3: Publish the event
To publish an event we need to check that event is null or not. This method is responsible for notifying all the subscribers.
  1. protected virtual void OnExamStarted()  
  2. {  
  3.     // Invoke the event  
  4.     if (ExamStarted != null)  
  5.     {  
  6.         ExamStarted(this, EventArgs.Empty);  
  7.     }  
  8. }   
Here we can see that there are two parameters passed in ExamStarted method, the first parameter (this) which is for the source of the event (current objects) and the second one is to send additional data with that event (this time it’s empty).

Register a Handler for that Event:

This is done with += operators. We can also have multiple functions registering for the same event; all registered functions are called one by one.
  1. objTest.ExamStarted += objNotify.OnExamStarted;   
If we want to remove any function, the -= operator is used.
  1. objTest.ExamStarted -= objNotify.OnExamStarted;  
 
Example of Sending Event Arguments
Let’s modify the previous example, this time we will add a new class called ExamEventArgs which has a property named examTime.

The class ExamEventArgs is inheriting from EventArgs.
  1. public class ExamEventArgs : EventArgs  
  2. {  
  3.         public int examTime { getset; }  
  4. }   
And instead of Empty arguments
  1. ExamStarted(this, EventArgs.Empty);   
We are using a new instance of ExamEventArgs with initializing time to 10.
  1. ExamStarted(thisnew ExamEventArgs  
  2. {  
  3.     examTime = 10  
  4. });  
 
Finally Merged sample Example:
  1. namespace Events  
  2. {  
  3.     public class ExamEventArgs : EventArgs  
  4.     {  
  5.         public int examTime { getset; }  
  6.     }  
  7.   
  8.     class Program  
  9.     {  
  10.         static void Main(string[] args)  
  11.         {  
  12.             IQTest objTest = new IQTest(); //Publisher  
  13.             NotificationService objNotify = new NotificationService(); //Subscriber  
  14.   
  15.             // += Register a Handler for that Event  
  16.             objTest.ExamStarted += objNotify.OnExamStarted;  
  17.   
  18.             objTest.myExam();  
  19.             Console.Read();  
  20.         }  
  21.     }  
  22.   
  23.     //Publisher or Sender  
  24.     class IQTest  
  25.     {  
  26.         //Delegate  
  27.         public delegate void ExamEventHandler(object source, ExamEventArgs args);  
  28.   
  29.         //Event  
  30.         public event ExamEventHandler ExamStarted;  
  31.   
  32.         public void myExam()  
  33.         {  
  34.             Console.WriteLine("Exam is Starting..");  
  35.             Thread.Sleep(2000);  
  36.             OnExamStarted();  
  37.         }  
  38.   
  39.         //This method will notify the subscriber   
  40.         protected virtual void OnExamStarted()  
  41.         {  
  42.             // Invoke the event  
  43.             if (ExamStarted != null)  
  44.             {  
  45.                 ExamStarted(thisnew ExamEventArgs  
  46.                 {  
  47.                     examTime = 10  
  48.                 });  
  49.             }  
  50.         }  
  51.     }  
  52.   
  53.     //Subscriber or Receiver  
  54.     class NotificationService  
  55.     {  
  56.         //Handler : That Match Delegate Signature  
  57.         public void OnExamStarted(object source, ExamEventArgs e)  
  58.         {  
  59.             Console.WriteLine("Your Time starts now | start answering..");  
  60.             Console.WriteLine("Exam Start Time: " + e.examTime);  
  61.         }  
  62.     }  
  63. }   
Output:
Exam is Starting..
Your Time starts now | start answering..
Exam Start Time: 10
 
Types of Event Handler: 
There are two forms of  event handler one is Normal form and one is Generic form. Here they are:

  1. Normal Form. - EventHandler
  2. Generic Form. - EventHandler<T>
Our previous example was with normal form of EventHandler.
 
Instead of creating our own we can use this Generic form. Let’s modify the previous example instead of using our own custom delegate
  1. //Delegate  
  2. public delegate void ExamEventHandler(object source, ExamEventArgs args);  
  3.   
  4. //Event  
  5. public event ExamEventHandler ExamStarted;  

We can use a single line of code, and the output will be the same as previous. 

  1. //EventHandler<TEventArgs>  
  2. public event EventHandler<ExamEventArgs> ExamStarted;  
 Finally sample Example:
  1. namespace Events  
  2. {  
  3.     public class ExamEventArgs : EventArgs  
  4.     {  
  5.         public int examTime { getset; }  
  6.     }  
  7.   
  8.     class Program  
  9.     {  
  10.         static void Main(string[] args)  
  11.         {  
  12.             IQTest objTest = new IQTest(); //Publisher  
  13.             NotificationService objNotify = new NotificationService(); //Subscriber  
  14.   
  15.             // += Register a Handler for that Event  
  16.             objTest.ExamStarted += objNotify.OnExamStarted;  
  17.   
  18.             objTest.myExam();  
  19.             Console.Read();  
  20.         }  
  21.     }  
  22.   
  23.     //Publisher or Sender  
  24.     class IQTest  
  25.     {  
  26.         //EventHandler<TEventArgs>  
  27.         public event EventHandler<ExamEventArgs> ExamStarted;  
  28.         public void myExam()  
  29.         {  
  30.             Console.WriteLine("Exam is Starting..");  
  31.             Thread.Sleep(2000);  
  32.             OnExamStarted();  
  33.         }  
  34.   
  35.         //This method will notify the subscriber   
  36.         protected virtual void OnExamStarted()  
  37.         {  
  38.             // Invoke the event  
  39.             if (ExamStarted != null)  
  40.             {  
  41.                 ExamStarted(thisnew ExamEventArgs  
  42.                 {  
  43.                     examTime = 10  
  44.                 });  
  45.             }  
  46.         }  
  47.     }  
  48.   
  49.     //Subscriber or Receiver  
  50.     class NotificationService  
  51.     {  
  52.         //Handler : That Match Delegate Signature  
  53.         public void OnExamStarted(object source, ExamEventArgs e)  
  54.         {  
  55.             Console.WriteLine("Your Time starts now | start answering..");  
  56.             Console.WriteLine("Exam Start Time: " + e.examTime);  
  57.         }  
  58.     }  
  59. }   
Output:
Exam is Starting..
Your Time starts now | start answering..
Exam Start Time: 10
 
Overview:
  1. Events are implemented with delegates.
  2. Events communicate in-between of objects.
  3. A method that handles an event is called an event handler.
  4. To build loosely coupled applications events are helpful.
  5. We can extend application by adding new methods without changing other parts of the code.