引言

如果你看过了 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  }
View Code

相关文章: