理解事件机制
来源:互联网 发布:人工智能 新药研发 编辑:程序博客网 时间:2024/05/21 06:51
在所有关于C#事件机制的介绍中,我更倾向于发布者/订阅者(Publisher/Subscriber)这种描述。理解事件机制并不是一件容易的事情,它所涉及的思想值得我们好好去研究。
本文资源来自《C#与.NET技术平台实战演练》——中国青年出版社
谈到事件,我们涉及到两个角色:事件发布者(Publisher)和事件订阅者(Scriber),也可以说是事件发送者(Sender)和事件接收者(Receiver)的关系。举个例子来说,市面上目前有许多杂志,杂志的种类也很多。而我只对其中的某些感兴趣,那么我就可以向杂志发行商提出订阅。之后,每当杂志发行时,我就会收到我在杂志发行商那儿订阅的杂志。在这个关系中,杂志发行商就相当于事件发行者,而我就是事件订阅者。每当杂志发行时,就触发了一个发行事件。
用面向对象的语言解释,这两者的意义如下:
事件发行者(Publisher)
它是一个对象,且会维护自身的状态信息。每当状态信息发生变动时,便触发一个事件,并通知所有的事件订阅者。对于杂志发行商来说,每本杂志都有自己的信息在里面,当杂志发行时,我要通知订阅该杂志的人:杂志已经发行啦,请注意查收!
事件接收者(Receiver)
这个对象要注册它感兴趣的对象,也就是订阅它自己喜欢的杂志啦。另外,这个对象通常要提供一个事件处理方法,在事件发行者触发一个事件后,会自动执行这个方法。对于上面所举的例子来说,也就是我收到杂志后要做什么事情,比如,你可以满世界地大喊:我收到杂志啦!也可以将杂志收藏起来慢慢欣赏,具体怎么实现完全取决你自己的喜好。
以下是.NET事件处理机制的模型:
下面给一个简单的例子,用以阐述事件的思想:
2using System.Collections.Generic;
3using System.Text;
4
5namespace EventDemo
6{
7 public delegate void SalaryCompute(); //声明一个代理类
8
9 public class Employee
10 {
11 public event SalaryCompute OnSalaryCompute; //定义事件,将其与代理绑定
12
13 public virtual void FireEvent() //触发事件的方法
14 {
15 if (OnSalaryCompute != null)
16 {
17 OnSalaryCompute(); //触发事件
18 }
19 }
20 }
21
22 public class HumanResource
23 {
24 public void SalaryHandler() //事件处理函数
25 {
26 Console.WriteLine("Salary"); //只是打印一行字而已
27 }
28
29 public static void Main()
30 {
31 Employee ep = new Employee();
32 HumanResource hr = new HumanResource();
33 ep.OnSalaryCompute+=new SalaryCompute(hr.SalaryHandler); //注册
34 ep.FireEvent(); //触发事件
35 Console.Read();
36 }
37 }
38}
39
与之相对应,HumanResource类则相当于一个事件订阅者(Subscriber),它定义了一个事件处理函数(SalaryHandler()),并用+=将其与事件联系起来,从而使事件触发的时候能够调用我这个方法(在本例中也就是打印一行字啦)。值得注意的一点是,事件处理函数的方法签名要与代理的方法签名相同,这是非常重要的一点。
下面将这个例子改造一下,事件参数信息,用以完善事件机制。
2using System.Collections.Generic;
3using System.Text;
4using System.Threading;
5
6namespace EventDemo
7{
8 public delegate void SalaryCompute(object sender,MyEventArgs e); //声明一个代理类
9
10 public class Employee
11 {
12 public event SalaryCompute OnSalaryCompute; //定义事件,将其与代理绑定
13
14 public virtual void FireEvent(MyEventArgs e) //触发事件的方法
15 {
16 if (OnSalaryCompute != null)
17 {
18 OnSalaryCompute(this,e); //触发事件
19 }
20 }
21 }
22
23 public class MyEventArgs : EventArgs //定义事件参数类
24 {
25 public readonly double _salary;
26 public MyEventArgs(double salary)
27 {
28 this._salary = salary;
29 }
30 }
31
32 public class HumanResource
33 {
34 public void SalaryHandler(object sender,MyEventArgs e) //事件处理函数,其签名应与代理签名相同
35 {
36 Console.WriteLine("Salary is {0}",e._salary); //只是打印一行字而已
37 }
38
39 public static void Main()
40 {
41 Employee ep = new Employee();
42 HumanResource hr = new HumanResource();
43 MyEventArgs e = new MyEventArgs(123.40);
44 ep.OnSalaryCompute+=new SalaryCompute(hr.SalaryHandler); //注册
45 for (; ; )
46 {
47 Thread.Sleep(1000); //让程序“睡”一秒
48 ep.FireEvent(e); //触发事件
49 }
50 //Console.Read();
51 }
52 }
53}
54
- 理解事件机制
- JavaScript 事件机制理解
- 深入理解JAVA事件机制
- 深入理解JAVA事件机制
- 深入理解JAVA事件机制
- 理解Flash中的事件机制
- 理解.net中的事件机制
- 理解NodeJS事件循环机制
- 深入理解JAVA事件机制
- android事件机制个人理解
- 理解Flex的事件机制
- 事件分发机制简单理解
- Java事件机制理解及应用
- Java事件机制理解及应用
- Java事件机制理解及应用
- Java事件机制理解及应用
- 对AS3.0事件机制的理解
- 深入理解Flex的事件机制
- 蓝桥杯-- 基础练习 十六进制转八进制(大数操作)
- context.getClass和getPackageName的区别
- 利用引用,对3个数按从大到小排列
- 自定义下拉控件dropdownlist,绑定数据更方便
- TP-link 无线路由器WDS设置方法图解_无线桥接设置 详细出处参考:http://www.jb51.net/softjc/39394.html
- 理解事件机制
- C#链表;单向链表
- struts2配置问题
- 如何给Winform 的Panel控件添加滚动条
- 别让用户发呆—设计中的防呆策略
- JSON基础示例
- HTTP协议及其POST与GET操作差异 & C#中如何使用POST、GET等
- 【动态规划】景观调整
- Linux内核用到的Radix Tree(转)