This scenario involves three consumers and two events from the same event source. Two of the consumers will be listening to the same event, while the third consumer will be monitoring another event.
In this example, a WaterTank (the event source) fills up slowly. Two interested consumers, the EmergencyAlarm and the FlashingLight, want to be notified when the water level reaches 20 m so that they can start ringing and flashing to attract attention. The warnings are supposed to prompt the duty officer to rush over, pump out the water manually, and turn off the alarm and light. If he has had too much alcohol the night before and does not respond to the din, an Electrode (somehow attached to his body) should fire small electric shocks so that he awakes. The Electrode is the third consumer which wants to be notified when the water level reaches 25 m – just before the WaterTank overflows at 30 m.
To make things a bit different from the previous example, each consumer class has its own constructor which takes in a WaterTank object. Registration of the event handler to the appropriate event is done in these constructors.
I have also coded a special event object class, OverflowRiskEventArgs, which contains a string message field and an int field indicating the water level. Figure 15.3 shows the scenario and the code follows.
1: using System; 2: /* ---------------------------------------- 3: * Delegate declaration 4: * ---------------------------------------*/ 5: delegate void WaterTankEventHandler 6: (object sender, OverflowRiskEventArgs e); 7: 8: /* ---------------------------------------- 9: * Event object 10: * ----------------------------------------*/ 11: class OverflowRiskEventArgs:EventArgs{ 12: private string Message; 13: private int WaterLevel; 14: 15: // constructor 16: public OverflowRiskEventArgs(string Message, int WaterLevel):base(){ 17: this.Message = Message; 18: this.WaterLevel = WaterLevel; 19: } 20: 21: // accessor methods 22: public string getMessage(){ 23: return Message; 24: } 25: 26: public int getWaterLevel(){ 27: return WaterLevel; 28: } 29: } 30: 31: /* ---------------------------------------- 32: * Event Source 33: * ----------------------------------------*/ 34: class WaterTank{ 35: public event WaterTankEventHandler WaterLevelReached20; 36: public event WaterTankEventHandler WaterLevelReached25; 37: 38: private int WaterLevel = 0; 39: 40: public void Run(){ 41: // water level increases in steps of 1 42: while (WaterLevel<30){ 43: WaterLevel += 1; 44: 45: Console.WriteLine("tank: Current water level: "+WaterLevel); 46: 47: // Fire WaterLevelReached20 event 48: if (WaterLevel==20) 49: WaterLevelReached20(this, 50: new OverflowRiskEventArgs("Please bail out",WaterLevel)); 51: 52: // Fire WaterLevelReached25 event 53: if (WaterLevel==25) 54: WaterLevelReached25(this, 55: new OverflowRiskEventArgs("Overflow imminent",WaterLevel)); 56: } 57: Console.WriteLine("tank: Overflowed."); 58: } 59: } 60: 61: /* ---------------------------------------- 62: * Event consumer 1 63: * ----------------------------------------*/ 64: class EmergencyAlarm{ 65: 66: // constructor 67: public EmergencyAlarm (WaterTank wt){ 68: wt.WaterLevelReached20 += new WaterTankEventHandler(this.Ring); 69: } 70: 71: // event handler 72: public void Ring (object sender, OverflowRiskEventArgs e){ 73: Console.WriteLine("alarm: Message : "+e.getMessage()); 74: Console.WriteLine("alarm: WaterLevel: "+e.getWaterLevel()); 75: Console.WriteLine("alarm: Ringing ..."); 76: } 77: } 78: 79: /* ---------------------------------------- 80: * Event consumer 2 81: * ----------------------------------------*/ 82: class FlashingLight{ 83: 84: // constructor 85: public FlashingLight (WaterTank wt){ 86: wt.WaterLevelReached20 += new WaterTankEventHandler(this.Flash); 87: } 88: 89: // event handler 90: public void Flash (object sender, OverflowRiskEventArgs e){ 91: Console.WriteLine("light: Message : "+e.getMessage()); 92: Console.WriteLine("light: WaterLevel: "+e.getWaterLevel()); 93: Console.WriteLine("light: Flashing light ..."); 94: } 95: } 96: 97: /* ---------------------------------------- 98: * Event consumer 3 99: * ----------------------------------------*/ 100: class Electrode{ 101: 102: // constructor 103: public Electrode (WaterTank wt){ 104: wt.WaterLevelReached25 +=new WaterTankEventHandler(this.SendShock); 105: } 106: 107: // event handler 108: public void SendShock (object sender, OverflowRiskEventArgs e){ 109: Console.WriteLine("electrode: Message : "+e.getMessage()); 110: Console.WriteLine("electrode: WaterLevel: "+e.getWaterLevel()); 111: Console.WriteLine("electrode: Sending Shocks ..."); 112: } 113: } 114: /* ---------------------------------------- 115: * Main class 116: * ----------------------------------------*/ 117: class TestClass{ 118: 119: public static void Main(){ 120: WaterTank wt = new WaterTank(); 121: EmergencyAlarm alarm = new EmergencyAlarm (wt); 122: FlashingLight light = new FlashingLight (wt); 123: Electrode electrode = new Electrode (wt); 124: 125: // the fun starts 126: wt.Run(); 127: } 128: }
Output:
c:expt>test tank: Current water level: 1 tank: Current water level: 2 tank: Current water level: 3 tank: Current water level: 4 tank: Current water level: 5 tank: Current water level: 6 tank: Current water level: 7 tank: Current water level: 8 tank: Current water level: 9 tank: Current water level: 10 tank: Current water level: 11 tank: Current water level: 12 tank: Current water level: 13 tank: Current water level: 14 tank: Current water level: 15 tank: Current water level: 16 tank: Current water level: 17 tank: Current water level: 18 tank: Current water level: 19 tank: Current water level: 20 alarm: Message : Please bail out alarm: WaterLevel: 20 alarm: Ringing ... light: Message : Please bail out light: WaterLevel: 20 light: Flashing light ... tank: Current water level: 21 tank: Current water level: 22 tank: Current water level: 23 tank: Current water level: 24 tank: Current water level: 25 electrode: Message : Overflow imminent electrode: WaterLevel: 25 electrode: Sending shocks ... tank: Current water level: 26 tank: Current water level: 27 tank: Current water level: 28 tank: Current water level: 29 tank: Current water level: 30 tank: Overflowed.
52.15.135.175