C# Event
Event is essentially a user action such as pressing a key, clicking, moving the mouse, etc., or some informational message such as a system-generated notification. Applications need to respond to events when they occur. For example, interrupts.
C# uses an event mechanism to implement inter-thread communication.
Using Delegates with Events
Events are declared and generated within a class and are associated with event handlers using delegates within the same class or other classes. The class containing the event is used to publish the event. This is known as the publisher class. Classes that receive the event are called subscribers classes. Events use the publisher-subscriber model.
Publisher is an object that contains the definition of the event and the delegate. The connection between the event and the delegate is also defined in this object. The publisher class's object invokes the event and notifies other objects.
Subscriber is an object that accepts the event and provides an event handler. The delegate in the publisher class invokes the method (event handler) in the subscriber class.
Declaring an Event
To declare an event inside a class, you must first declare the delegate type for the event. For example:
public delegate void BoilerLogHandler(string status);
Then, declare the event itself using the event keyword:
// Based on the above delegate, define the event
public event BoilerLogHandler BoilerEventLog;
The above code defines a delegate named BoilerLogHandler and an event named BoilerEventLog that will invoke the delegate when triggered.
Example
Example 1
using System;
namespace SimpleEvent
{
using System;
/***********Publisher Class***********/
public class EventTest
{
private int value;
public delegate void NumManipulationHandler();
public event NumManipulationHandler ChangeNum;
protected virtual void OnNumChanged()
{
if (ChangeNum != null)
{
ChangeNum(); /* Event is triggered */
}
else
{
Console.WriteLine("event not fire");
Console.ReadKey(); /* Press enter to continue */
}
}
public EventTest()
{
int n = 5;
SetValue(n);
}
public void SetValue(int n)
{
if (value != n)
{
value = n;
OnNumChanged();
}
}
}
/***********Subscriber Class***********/
public class subscribEvent
{
public void printf()
{
Console.WriteLine("event fire");
Console.ReadKey(); /* Press enter to continue */
}
}
/***********Trigger***********/
public class MainClass
{
public static void Main()
{
EventTest e = new EventTest(); /* Instantiate object, first time event not triggered */
subscribEvent v = new subscribEvent(); /* Instantiate object */
e.ChangeNum += new EventTest.NumManipulationHandler(v.printf); /* Register */
e.SetValue(7);
e.SetValue(11);
}
}
}
When the above code is compiled and executed, it produces the following result:
event not fire
event fire
event fire
This example provides a simple application for troubleshooting hot water boiler systems. When a maintenance engineer inspects the boiler, the boiler's temperature and pressure are automatically recorded into the log file along with the engineer's notes.
Example 2
using System;
using System.IO;
namespace BoilerEventAppl
{
// Boiler class
class Boiler
{
private int temp;
private int pressure;
public Boiler(int t, int p)
{
temp = t;
pressure = p;
}
public int getTemp()
{
return temp;
}
public int getPressure()
{
return pressure;
}
}
// Event publisher
class DelegateBoilerEvent
{
public delegate void BoilerLogHandler(string status);
// Define event based on the above delegate
public event BoilerLogHandler BoilerEventLog;
public void LogProcess()
{
string remarks = "O. K";
Boiler b = new Boiler(100, 12);
int t = b.getTemp();
int p = b.getPressure();
if(t > 150 || t < 80 || p < 12 || p > 15)
{
remarks = "Need Maintenance";
}
OnBoilerEventLog("Logging Info:\n");
OnBoilerEventLog("Temperature " + t + "\nPressure: " + p);
OnBoilerEventLog("\nMessage: " + remarks);
}
protected void OnBoilerEventLog(string message)
{
if (BoilerEventLog != null)
{
BoilerEventLog(message);
}
}
}
// This class retains the terms for writing to the log file
class BoilerInfoLogger
{
FileStream fs;
StreamWriter sw;
public BoilerInfoLogger(string filename)
{
fs = new FileStream(filename, FileMode.Append, FileAccess.Write);
sw = new StreamWriter(fs);
}
public void Logger(string info)
{
sw.WriteLine(info);
}
public void Close()
{
sw.Close();
fs.Close();
}
}
// Event subscriber
public class RecordBoilerInfo
{
static void Logger(string info)
{
Console.WriteLine(info);
}//end of Logger
static void Main(string[] args)
{
BoilerInfoLogger filelog = new BoilerInfoLogger("e:\\boiler.txt");
DelegateBoilerEvent boilerEvent = new DelegateBoilerEvent();
boilerEvent.BoilerEventLog += new DelegateBoilerEvent.BoilerLogHandler(filelog.Logger);
boilerEvent.LogProcess();
filelog.Close();
}//end of main
}//end of RecordBoilerInfo
}//end of namespace
boilerEvent.BoilerEventLog += new DelegateBoilerEvent.BoilerLogHandler(Logger);
boilerEvent.BoilerEventLog += new DelegateBoilerEvent.BoilerLogHandler(filelog.Logger);
boilerEvent.LogProcess();
Console.ReadLine();
filelog.Close();
} // end of main
} // end of RecordBoilerInfo
}
When the above code is compiled and executed, it produces the following result:
Logging info:
Temperature 100
Pressure 12
Message: O. K