Meta Description
Learn how to master events in C# with a step-by-step guide. This article explains the publish-subscribe pattern using a simple temperature monitoring system, with clear examples and hands-on assignments from beginner to advanced levels.
Events in C# are a fundamental language feature that enables different parts of an application to communicate without tight coupling. They are widely used in scenarios such as UI interactions, background processing, monitoring systems, and alerting mechanisms.
At the core of events lies the publish-subscribe pattern, where one object publishes notifications and other objects subscribe to react when something happens.
In this article, you’ll learn how events work in C# by building a simple temperature monitoring system. The example is intentionally small and easy to follow, allowing you to focus on the concept itself. You’ll also find practical assignments at different difficulty levels to reinforce what you learn.
1. What Are Events in C#?
Events in C# are built on top of delegates, but they add an important layer of structure and safety.
They allow an object to notify other objects that something has happened, without knowing who is listening. This is what makes events a powerful tool for building loosely coupled systems.
Typical use cases for events include:
- Button clicks in UI applications
- Notifications and alerts
- Monitoring systems
- Background services reacting to changes
In our example, a temperature sensor will raise an event when the temperature exceeds a specific threshold.
2. Temperature Monitoring System Example
We will build a simple system that:
- Monitors room temperature
- Raises an event when the temperature exceeds 30°C
- Notifies any subscribed listeners
Step 1: Define the Event
We start by defining an event inside the TemperatureSensor class.
using System;
public class TemperatureSensor
{
// Define the event using EventHandler<T>
public event EventHandler<TemperatureEventArgs> TemperatureExceeded;
private int _currentTemperature;
// Simulate temperature changes
public void CheckTemperature(int temperature)
{
_currentTemperature = temperature;
Console.WriteLine($"Current temperature: {_currentTemperature}°C");
if (_currentTemperature > 30)
{
OnTemperatureExceeded(_currentTemperature);
}
}
// Protected virtual method to raise the event
protected virtual void OnTemperatureExceeded(int temperature)
{
TemperatureExceeded?.Invoke(
this,
new TemperatureEventArgs(temperature)
);
}
}
Custom Event Arguments
public class TemperatureEventArgs : EventArgs
{
public int Temperature { get; }
public TemperatureEventArgs(int temperature)
{
Temperature = temperature;
}
}
Explanation
-
TemperatureExceededis an event declared usingEventHandler<T>, which follows .NET conventions. - The
CheckTemperaturemethod simulates temperature readings. - When the temperature exceeds 30°C, the event is raised.
- The
OnTemperatureExceededmethod is marked asprotected virtualto allow derived classes to override how the event is raised if needed. - The null-conditional operator (
?.) ensures the event is raised safely only when there are subscribers.
Step 2: Subscribe to the Event
Now we create a subscriber that listens for the event and reacts when it occurs.
public class Program
{
public static void Main(string[] args)
{
TemperatureSensor sensor = new TemperatureSensor();
// Subscribe to the event
sensor.TemperatureExceeded += Sensor_TemperatureExceeded;
// Simulate temperature readings
sensor.CheckTemperature(25); // No alert
sensor.CheckTemperature(32); // Alert triggered
}
private static void Sensor_TemperatureExceeded(
object sender,
TemperatureEventArgs e)
{
Console.WriteLine(
$"Alert! Temperature exceeded: {e.Temperature}°C"
);
}
}
Explanation
- The
Programclass subscribes to theTemperatureExceededevent. -
Sensor_TemperatureExceededis the event handler method. - When the event is raised, the handler executes automatically.
- The publisher does not know who is listening — it only knows that someone might be interested.
3. How the Publish-Subscribe Pattern Works Here
Publisher: TemperatureSensor
- Responsible for monitoring temperature
- Raises an event when a condition is met
- Does not depend on any subscriber implementation
Subscriber: Program
- Listens for the event
- Reacts when the event is raised
- Can be replaced or extended without modifying the publisher
This separation is what makes events so valuable in larger systems.
4. Event Patterns and Best Practices in C
When working with events in C#, keep the following best practices in mind:
Use
EventHandlerorEventHandler<T>
This keeps your code consistent with .NET standards.Name events in the past tense
Examples:TemperatureExceeded,FileDownloaded.Raise events through a protected virtual method
This enables extensibility and follows the official .NET event pattern.Never expose events as public delegates
Always use theeventkeyword to prevent external code from invoking the event directly.Unsubscribe when no longer needed
Failing to unsubscribe can lead to memory leaks, especially in long-lived applications.
5. Assignments to Practice Events in C
Easy Level
Add a new event called TemperatureDropped that is raised when the temperature drops below 10°C.
Hint:
Create a second event and raise it inside CheckTemperature when the value is less than 10.
Medium Level
Allow multiple subscribers to react to the same event.
Examples:
- One subscriber prints an alert to the console
- Another subscriber logs the alert to a file
Hint:
Attach multiple event handlers to the same event.
Difficult Level
Extend the system to monitor both temperature and humidity.
Requirements:
- Raise an event when temperature exceeds 30°C
- Raise an event when humidity exceeds 70%
- Pass both values using a custom event arguments class
Hint:
Extend TemperatureEventArgs or create a new event args class that includes humidity.
Conclusion
Events are a core mechanism in C# for implementing the publish-subscribe pattern. They enable clean communication between components while keeping your code loosely coupled and easy to extend.
By working through this temperature monitoring example, you’ve learned how to:
- Define events using standard .NET patterns
- Raise events safely
- Subscribe and react to events
- Apply best practices that scale to real applications
Mastering events will help you build systems that are easier to maintain, test, and evolve as your applications grow.

Top comments (0)