引言
如果你看过了 C#中的委托和事件 一文,我想你对委托和事件已经有了一个基本的认识。但那些远不是委托和事件的全部内容,还有很多的地方没有涉及。本文将讨论委托和事件一些更为细节的问题,包括一些大家常问到的问题,以及事件访问器、异常处理、超时处理和异步方法调用等内容。
为什么要使用事件而不是委托变量?
在 C#中的委托和事件 中,我提出了两个为什么在类型中使用事件向外部提供方法注册,而不是直接使用委托变量的原因。主要是从封装性和易用性上去考虑,但是还漏掉了一点,事件应该由事件发布者触发,而不应该由客户端(客户程序)来触发。这句话是什么意思呢?请看下面的范例:
NOTE:注意这里术语的变化,当我们单独谈论事件,我们说发布者(publisher)、订阅者(subscriber)、客户端(client)。当我们讨论Observer模式,我们说主题(subject)和观察者(observer)。客户端通常是包含Main()方法的Program类。
1 class Program { 2 static void Main(string[] args) { 3 Publishser pub = new Publishser(); 4 Subscriber sub = new Subscriber(); 5 6 pub.NumberChanged += new NumberChangedEventHandler(sub.OnNumberChanged); 7 pub.DoSomething(); // 应该通过DoSomething()来触发事件 8 pub.NumberChanged(100); // 但可以被这样直接调用,对委托变量的不恰当使用 9 } 10 } 11 12 // 定义委托 13 public delegate void NumberChangedEventHandler(int count); 14 15 // 定义事件发布者 16 public class Publishser { 17 private int count; 18 public NumberChangedEventHandler NumberChanged; // 声明委托变量 19 //public event NumberChangedEventHandler NumberChanged; // 声明一个事件 20 21 public void DoSomething() { 22 // 在这里完成一些工作 ... 23 24 if (NumberChanged != null) { // 触发事件 25 count++; 26 NumberChanged(count); 27 } 28 } 29 } 30 31 // 定义事件订阅者 32 public class Subscriber { 33 public void OnNumberChanged(int count) { 34 Console.WriteLine("Subscriber notified: count = {0}", count); 35 } 36 }