C# events
Events are very helpful in managing interactions between calling object and called object. In this example we capture the essence of c# events. Here’s how the discussion between two objects goes:
- Object COUNTER has an internal counter that can be incremented by AddOne() method
- Program initializes Object 1 and sets the threshold to 5
- Program calls Object 1’s AddOne() method 10 times. From 6th to 10th time the threshold will be surpassed
- Program wants to be notified whenever Object COUNTER’s total surpasses the threshold
- Object COUNTER exposes a public event
- Program wires up that event to one of its method so that it can listen when COUNTER fires the event
- Object COUNTER checks when the threshold is surpassed. If surpassed, it sends the event’s listener information
- Program catches this message and displays appropriate message
Let’s look at the example based on http://msdn.microsoft.com/en-us/library/9aackb16(v=vs.110).aspx. It was modified by adding comments and relevant variable names to build an easy-to-use example for myself.
using System;
using System.Globalization;
namespace EventTest
{
/// <summary>
/// Custom event argument to hold data of our choice
/// </summary>
class PgmArgs : EventArgs
{
public string Data { get; set; }
}
/// <summary>
/// Counter class adds 1 to its total until threshold is reach
/// When threshold is reached, an event is fired. This event can be
/// handled by the calling method
/// </summary>
class Counter
{
public event EventHandler ThresholdReached;
private readonly int _threshold;
private int _total;
/// <summary>
/// Constructor initializes the threshold
/// </summary>
/// <param name="threshold">Invoke an event after this threshold is surpassed</param>
public Counter(int threshold)
{
_threshold = threshold;
}
/// <summary>
/// Keep on adding to the total. Invoke overflow method if total surpasses threshold
/// </summary>
public void AddOne()
{
_total++;
if (_total <= _threshold) return;
var args = new PgmArgs { Data = _total.ToString(CultureInfo.InvariantCulture) };
OnOverflow(args);
}
/// <summary>
/// Check if our event is wired up by any handler-methods
/// If so, invoke that (just like invoking a delegate)
/// </summary>
/// <param name="e">Custom event argument we created</param>
private void OnOverflow(EventArgs e)
{
var handler = ThresholdReached;
if (handler != null)
{
handler(this, e);
}
}
}
/// <summary>
/// Let's test events
/// </summary>
class Program
{
static void Main()
{
// create the counter class and set threshold to 5
// keep on adding data until threshold is surpassed
var c = new Counter(5);
// wire up our event handler c_ThresholdReached with Counter's event
c.ThresholdReached += c_ThresholdReached;
// force an overflow of threshold and allow c_ThresholdReached to handle it
for (var i = 1; i < 10; i++)
{
c.AddOne();
}
Console.Read();
}
/// <summary>
/// When overflow happens in Counter, this method will be called because we
/// told Counter's event variable to talk to this method
/// </summary>
/// <param name="sender">Sender of event</param>
/// <param name="e">Event arguments sent to us by the sender</param>
static void c_ThresholdReached(object sender, EventArgs e)
{
Console.WriteLine("Sender " + sender + " tells us that " + ((PgmArgs)e).Data + " surpassed threshold");
}
}
}
Results:
Sender EventTest.Counter tells us that 6 surpassed threshold
Sender EventTest.Counter tells us that 7 surpassed threshold
Sender EventTest.Counter tells us that 8 surpassed threshold
Sender EventTest.Counter tells us that 9 surpassed threshold
Sender EventTest.Counter tells us that 10 surpassed threshold