C# 事件

事件(Event) 基本上说是一个用户操作,如按键、点击、鼠标移动等等,或者是一些出现,如系统生成的通知。应用程序需要在事件发生时响应事件。例如,中断。事件是用于进程间通信。

一、通过事件使用委托

事件在类中声明且生成,且通过使用同一个类或其他类中的委托与事件处理程序关联。包含事件的类用于发布事件。这被称为 发布器(publisher) 类。其他接受该事件的类被称为 订阅器(subscriber) 类。事件使用 发布-订阅(publisher-subscriber) 模型。发布器(publisher) 是一个包含事件和委托定义的对象。事件和委托之间的联系也定义在这个对象中。发布器(publisher)类的对象调用这个事件,并通知其他的对象。

订阅器(subscriber) 是一个接受事件并提供事件处理程序的对象。在发布器(publisher)类中的委托调用订阅器(subscriber)类中的方法(事件处理程序)。

二、声明事件(Event)

在类的内部声明事件,首先必须声明该事件的委托类型。例如:

  1. public delegate void BoilerLogHandler(string status);

然后,声明事件本身,使用 event 关键字:

  1. // 基于上面的委托定义事件
  2. public event BoilerLogHandler BoilerEventLog;

上面的代码定义了一个名为 BoilerLogHandler 的委托和一个名为 BoilerEventLog 的事件,该事件在生成的时候会调用委托。

实例 1

  1. using System;
  2. namespace SimpleEvent
  3. {
  4. using System;
  5. /***********发布器类***********/
  6. public class EventTest
  7. {
  8. private int value;
  9. public delegate void NumManipulationHandler();
  10. public event NumManipulationHandler ChangeNum;
  11. protected virtual void OnNumChanged()
  12. {
  13. if ( ChangeNum != null )
  14. {
  15. ChangeNum(); /* 事件被触发 */
  16. }else {
  17. Console.WriteLine( "event not fire" );
  18. Console.ReadKey(); /* 回车继续 */
  19. }
  20. }
  21. public EventTest()
  22. {
  23. int n = 5;
  24. SetValue( n );
  25. }
  26. public void SetValue( int n )
  27. {
  28. if ( value != n )
  29. {
  30. value = n;
  31. OnNumChanged();
  32. }
  33. }
  34. }
  35. /***********订阅器类***********/
  36. public class subscribEvent
  37. {
  38. public void printf()
  39. {
  40. Console.WriteLine( "event fire" );
  41. Console.ReadKey(); /* 回车继续 */
  42. }
  43. }
  44. /***********触发***********/
  45. public class MainClass
  46. {
  47. public static void Main()
  48. {
  49. EventTest e = new EventTest(); /* 实例化对象,第一次没有触发事件 */
  50. subscribEvent v = new subscribEvent(); /* 实例化对象 */
  51. e.ChangeNum += new EventTest.NumManipulationHandler( v.printf ); /* 注册 */
  52. e.SetValue( 7 );
  53. e.SetValue( 11 );
  54. }
  55. }
  56. }

当上面的代码被编译和执行时,它会产生下列结果:

  1. event not fire
  2. event fire
  3. event fire

实例 2

本实例提供一个简单的用于热水锅炉系统故障排除的应用程序。当维修工程师检查锅炉时,锅炉的温度和压力会随着维修工程师的备注自动记录到日志文件中。

  1. using System;
  2. using System.IO;
  3. namespace BoilerEventAppl
  4. {
  5. // boiler 类
  6. class Boiler
  7. {
  8. private int temp;
  9. private int pressure;
  10. public Boiler(int t, int p)
  11. {
  12. temp = t;
  13. pressure = p;
  14. }
  15. public int getTemp()
  16. {
  17. return temp;
  18. }
  19. public int getPressure()
  20. {
  21. return pressure;
  22. }
  23. }
  24. // 事件发布器
  25. class DelegateBoilerEvent
  26. {
  27. public delegate void BoilerLogHandler(string status);
  28. // 基于上面的委托定义事件
  29. public event BoilerLogHandler BoilerEventLog;
  30. public void LogProcess()
  31. {
  32. string remarks = "O. K";
  33. Boiler b = new Boiler(100, 12);
  34. int t = b.getTemp();
  35. int p = b.getPressure();
  36. if(t > 150 || t < 80 || p < 12 || p > 15)
  37. {
  38. remarks = "Need Maintenance";
  39. }
  40. OnBoilerEventLog("Logging Info:\n");
  41. OnBoilerEventLog("Temparature " + t + "\nPressure: " + p);
  42. OnBoilerEventLog("\nMessage: " + remarks);
  43. }
  44. protected void OnBoilerEventLog(string message)
  45. {
  46. if (BoilerEventLog != null)
  47. {
  48. BoilerEventLog(message);
  49. }
  50. }
  51. }
  52. // 该类保留写入日志文件的条款
  53. class BoilerInfoLogger
  54. {
  55. FileStream fs;
  56. StreamWriter sw;
  57. public BoilerInfoLogger(string filename)
  58. {
  59. fs = new FileStream(filename, FileMode.Append, FileAccess.Write);
  60. sw = new StreamWriter(fs);
  61. }
  62. public void Logger(string info)
  63. {
  64. sw.WriteLine(info);
  65. }
  66. public void Close()
  67. {
  68. sw.Close();
  69. fs.Close();
  70. }
  71. }
  72. // 事件订阅器
  73. public class RecordBoilerInfo
  74. {
  75. static void Logger(string info)
  76. {
  77. Console.WriteLine(info);
  78. }//end of Logger
  79. static void Main(string[] args)
  80. {
  81. BoilerInfoLogger filelog = new BoilerInfoLogger("e:\\boiler.txt");
  82. DelegateBoilerEvent boilerEvent = new DelegateBoilerEvent();
  83. boilerEvent.BoilerEventLog += new
  84. DelegateBoilerEvent.BoilerLogHandler(Logger);
  85. boilerEvent.BoilerEventLog += new
  86. DelegateBoilerEvent.BoilerLogHandler(filelog.Logger);
  87. boilerEvent.LogProcess();
  88. Console.ReadLine();
  89. filelog.Close();
  90. }//end of main
  91. }//end of RecordBoilerInfo
  92. }

当上面的代码被编译和执行时,它会产生下列结果:

  1. Logging info:
  2. Temperature 100
  3. Pressure 12
  4. Message: O. K

🔚