C#中事件机制的理解

引自:http://www.csharpwin.com/csharpspace/2793.shtml

前些天狠狠心咬咬牙,从刚发的工资中拿出几十块大洋,又给老外投资了一笔,呵呵,还好投资方向没错,物超所值啊拥有了一本Jeffrey Richter前辈的<Microsoft .net框架程序设计>,现在已经看完前17章了,可谓是进展神速啊(小小滴自夸一下)
昨天和今天两天好好的把"委托"机制研究了一下,算是小有所明白了,想起来前些天看"事件"的时候,因为其中也涉及到了委托机制,所以都看得有些云里雾里的
第一遍看的时候,大多数地方都还看得明白,但是有个地方就一直没转过来.
书上说的是,定义了一个类以后,例如书中的例子是class 
MailManger(注意:该MailManger类之内还有一个描述mail消息的class
MailMsgEventArgs,也就是用来定义保存mail消息的东东,同时也是一个继承自EventArgs的类型,这是根据.net框架约定
的),这里,先贴一下它的代码

public class MailMsgEventArgs:EventArgs
 2{
 3public MailMsgEventArgs(String from,String to,String subject,String body)
 4{
 5this.from=from;
 6this.to=to;
 7this.subject=subject;
 8this.body=body;
 9}
10public readonly String from,to,subject,body;
11}

很明显,是一个用来描述的类型,具体没有多少内容,
然后,紧跟着又定义了一个委托,已经用这个委托类型(这里要插一句的是,我看完第十七章才知道委托在.net框架内部就是一个类型,所以才可以定义它的一个对象)来定义了一个事件对象(我现在的看法是,该事件对象也就是相当于一个class的对象)

delegate void MailMsgEventHandler(Object sender,MailMsgEventArgs args);
2
3public event MailMsgEventArgs MailMsg;

//should be ‘public event MailMsgEventHandler MailMsg;‘ sorry:)
其中有一些定义事件委托的代码规范是要注意一下的.
到这里就开始有点迷糊了,为什么就一定要这样用个委托转个弯来定义一个事件呢??
然后后文就开始谈到说,定义事件的这个类(在这里是MailManger)允许其他类的对象(书中的例子是Fax和Printer)登记该事件,然后在有
特定事件发生时(也就是这里的MailMsg事件),由事件宿主MailManger来通知它的事件登记者,告诉它们采取措施,例如Fax就应该立即
fax一份传真出来,打印机也就得老老实实的打印东东出来(嗯,看来这个事件机制真的很牛
 在后文中,就具体说明了MailMsg的工作机制,原来是C#编译器看到有这么一句以后,就把它翻译成三个构造,如下:

private MailMsgEventHandler MailMsg=null;
 2//我认为这里就是关键了,也就是指定了委托对象的头指针
 3
 4[MethodImplAttribute(MethodImplOptions.Synchronized)]
 5public virtual void add_MailMsg(MailMsgEventHandler handler)
 6{
 7MailMsg=(MailMsgEventHandler)Delegate.Combine(MailMsg,handler);
 8}
 9
10[MethodImpl(MethodImplOptions.Synchronized)]
11public virtual void remove_MailMsg(MailMsgEventaHandler handler)
12{
13MailMsg=(MailMsgEventHandler)Delegate.Remove(MailMsg,handler);
14}

仔细看了委托那一章的后几节才明白,实际上委托都是继承自MultiDelegate类型,而MultiDelegate又继承自Delegate类型,
而Delegate类型定义了两个方法(这里的virtual是不应该有的),其中的add方法就是把委托对象添加到委托链上,而remove方法则是把
委托对象从委托链上移出,没看委托一章时,虽然大致上明白这里两个方法的含义,但是不明白它们的真正内涵之所在.
前思后想,终于明白其中的真谛之所在,由于Delegate的机制,add了一个委托对象以后,就相当于在这个委托链上增加了一个委托对象,remove
了一个委托对象以后,就相当于在这个委托链上移出了一个委托对象,可以把这里的委托链理解为数据结构中的链表(我就是这么理解的),要对该委托链表进行操
作,只需要找到链表的尾巴(这里是tail,而不是head,可以从Delegate的重载方法中看出),然后依次进行操作.直到该委托链上的所有对象都
有操作完毕.
最开始一直不理解的是:因为虽然在Fax类型中确实把自身登记到该事件中去了,但是这个事件宿主是怎么知道都有谁已经登记了呢?如果不知道都有哪个对象已经登记了该事件,那又怎么去轮个通知呢?
看完了之后,才总算了解了委托的伟大之所在.
其实我认为最明白的想法就是,由事件宿主来维护一个委托对象(也就是它自己定义的事件,这里必须是一个委托对象),并且同时有该委托类型的一个对象(这里
肯定是一个引用对象),在事件登记者都已经操作完毕之后,也就是把自己添加到该委托对象的屁屁后面以后,该事件宿主只需要通知一个人,也就是它自己维护的
那个委托对象,因为是指针形式,就会自动也把自己屁屁后面的跟屁虫挨个都通知到,这样就达到了通知所有事件登记者的目的。

时间: 2024-10-06 03:45:57

C#中事件机制的理解的相关文章

关于Flex事件机制的理解

优点:减少同一个UI树上对象监听器数量,从而带来性能优化. 1.FLEX 事件机制是分为三个阶段. 捕获---〉目标----〉冒泡 所谓捕获:即是寻找目标的过程,是目标的父节点.注:起点是Stage,终点也是Stage. 所谓目标:即是找到目标. 所谓冒泡:可以理解为捕获的返过程. 此为官方图解. 事件的派发: Flex中可以通过dispatchEvent()方法手工派发事件, 所有UIComponent的子类都可以调用此方法.   语法:   objectInstance.dispatchEv

关于事件机制的理解

最近终于把事件机制弄明白了.和大家分享一下. 下面是定义的事件: package { import flash.events.Event; public class NBEEvent extends Event { /** * 对 */ public static const RIGHT: String = "nbe_event_right"; public function NBEEvent(type: String, bubbles: Boolean = true, cancela

C++中事件机制的简洁实现

事件模型是被广泛使用的好东西,但是C++标准库里没有现成的,其他实现又复杂或者不优雅,比如需要使用宏.现在VC11可以用在XP下了,那么就痛快的拿起C++11提供的先进设施组合出一个轻便的实现吧. 为了达到简洁的目的,需要放弃一些特性: 1.不支持判断函数是否已经绑定过(因为std::function不提供比较方法,自己实现function的话代码又变多了) 2.需要使用者接收返回的回调函数标识来移除事件绑定(原因同上) 3.事件没有返回值,不支持回调函数优先级.条件回调等事件高级特性(比如返回

js中事件流的理解

事件的概念: HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件.页面的滚动事件onscroll等等,可以向文档或者文档中的元素添加事件侦听器来预订事件. 想要知道这些事件是在什么时候进行调用的,就需要了解一下“事件流”的概念. 什么是事件流: 1,DOM事件流, 事件流包括三个阶段: 1,事件捕获阶段. 2,处于目标阶段.(当前事件阶段) 3,事件冒泡阶段. <!DOCTYPE html> <html lang="en"> <h

js 中事件的个人理解

事件 事件组成 1,触发谁的事件 事件源2,触发是什么事件 click mouseover mouseout3,事件触发之后,干什么 事件函数 (干什么写在事件函数中) 事件对象 类似于飞机的“黑匣子” 用于保存 一个事件发生的时候,所有的信息比如:事件发生时鼠标的坐标如何获取事件对象: 兼容性问题:在不同浏览器上 获取方法不一样 在IE 以及DOM标准:全局的对象(window下) 名字event 在高版本IE 以及 chrome 不支持event来获取事件对象的,另外一种方式 自动变成事件函

在Unity3D中基于订阅者模式实现事件机制

??各位朋友,大家好,欢迎大家关注我的博客,我是秦元培,我的博客地址是http://qinyuanpei.com.今天博主想和大家分享的是在Unity3D中基于订阅者模式实现消息传递机制,我们知道Unity3D中默认提供了一种消息传递机制SendMessage,虽然SendMessage使用起来的确非常简单,可是它的这种简单是建立在付出一定的代价的基础上的.经常有朋友提及不同的模块间如何进行通信的问题,可能答案最终会落到单例模式.委托和事件机制这些关键词上,在这种情况下本文所探讨的内容可能会帮助

[学习总结]4、Android的ViewGroup中事件的传递机制(一)

本文主要针对dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent三个方法,通过简单的例子来简单的介绍下. 根据字面意思的理解,dispatchTouchEvent分发触摸事件,onInterceptTouchEvent拦截触摸事件,onTouchEvent触摸事件.正如它们各自的字面意思,下面简单的列出各自的作用和用法. 1.dispatchTouchEvent作用:决定事件是否由onInterceptTouchEvent来拦截处理. 返回s

[学习总结]5、Android的ViewGroup中事件的传递机制(二)

下面是第一篇的连接 Android的ViewGroup中事件的传递机制(一) 关于onInterceptTouchEvent和onTouchEvent的详细解释. 1 public class MainActivity extends Activity { 2 Group1 group1; 3 Group2 group2; 4 MyTextView myTv; 5 6 /** Called when the activity is first created. */ 7 @Override 8

事件和消息机制的理解

消息/事件机制是几乎所有开发语言都有的机制,并不是deviceone的独创,在某些语言称之为消息(Event),有些地方称之为(Message). 其实原理是类似的,只不过有些实现的方式要复杂一点.我们deviceone统一就叫消息. 消息基础概念 还有一些初学者不太熟悉这个机制,我们先简单介绍一些基础概念,如果熟悉的人可以跳过这个部分.一个/条消息可以理解为是一个数据结构,包含以下几个基本部分: 消息源 :就是消息的来源,发出这个消息的对象 消息名 :就是消息的唯一标示 消息数据:消息发出后附