Microsoft.Net框架程序设计学习笔记(15):事件之原理分析
完整定义一个事件的方法
以Mail发送为例:
- 定义一个类型用于保存所有需要发送给事件通知接受者的附加信息。
按.Net框架约定,所有保存事件信息的类型都应该继承自System.EventArgs,且类型的名称应该EventArgs结束。public class MailMsgEventArgs : EventArgs
{
public readonly string from, to, subject, body;public MailMsgEventArgs(string from, string to, string subject, string body)
{
this.from = from;
this.to = to;
this.subject = subject;
this.body = body;
}
} - 定义一个委托类型,用于指定事件触发时被调用的方法原型。
按.Net框架约定,委托类型名称应该以EventHandler结束。另外,回调方法的原型应该有一个void返回值,并且接受两个参数。第1个参数为Object类型,指向发送通知的对象。第2个参数为一个继承自EventArgs的类型,其中包括所有通知接受者需要的附加信息。如果我们定义的事件没有需要传给事件接受者的附加信息,便不必定义新的委托类型。直接使用FCL中的System.EventHandler,并将EventArgs.Empty传递给第二个参数即可。EventHandler的原型为:public delegate void EventHandler(object sender, EventArgs e);public delegate void MailMsgEventHandler(Object sender, MailMsgEventArgs args); - 定义一个事件成员。
public event MailMsgEventHandler MailMsg;
- 定义一个受保护的虚方法,负责通知事件的登记对象。
protected virtual void OnMailMsg(MailMsgEventArgs e)
{
if(MailMsg != null)
{
MailMsg(this, e);
}
} - 定义一个方法,将输入转化为期望的事件。
public void SimulateArrivingMsg(string from, string to, string subject, string body)
{
MailMsgEventArgs e = new MailMsgEventArgs(from, to, subject, body);
OnMailMsg(e);
}
事件原理分析
现在让我们看看定义MailMsg事件时发生了些什么事情?
编译器在遇到事件定义语句:public event MailMsgEventHandler MailMsg会将这段代码翻译成以下3个构造:
private MailMsgEventHandler MailMsg = null;
//2.一个允许对象登记事件的公有add_*方法
[MethodImplAttribute(MethodImplOptions.Synchronized)]
public void add_MailMsg(MailMsgEventHandler handler)
{
MailMsg = (MailMsgEventHandler)Delegate.Combine(MailMsg, handler);
}
//3.一个允许对象注销事件的公有remove_*方法
[MethodImplAttribute(MethodImplOptions.Synchronized)]
public void remove_MailMsg(MailMsgEventHandler handler)
{
MailMsg = (MailMsgEventHandler)Delegate.Remove(MailMsg, handler);
}
第1步是构造一个委托类型的字段,该字段引用的是一个委托链表的首部,链表中包含了那些期望在事件发生时被通知的委托对象。当一个侦听者需要登记事件时,它只需将一个委托实例添加到委托链表上就可以了。
注意:登记和注销事件的方法应用了MethodImplAttribute特性,这个特性使方法被标识为同步方法,这使得它们得以实现线程安全,也就是说多个侦听者可以同时登记或注销事件,而不损坏委托链表。
侦听事件
登记、注销事件代码示例:
{
public Fax(MailManager mm)
{
mm.MailMsg += new MailManager.MailMsgEventHandler(FaxMsg);
private void FaxMsg(object sender, MailManager.MailMsgEventArgs e)
{
........
}
public void Unregister(MailManager mm)
{
mm.MailMsg -= new MailManager.MailMsgEventHandler(FaxMsg);
}
}
当一个对象不再希望接受事件通知时,应该注销该事件。
注意:只要一个对象仍然登记有另一个对象的事件,该对象就不可能被执行垃圾收集。如果我们的类型实现了IDisposable接口的Dispose方法,我们应该在其内部注销其登记的所有事件。
转载于:https://www.cnblogs.com/free722/archive/2011/03/27/1997203.html
Microsoft.Net框架程序设计学习笔记(15):事件之原理分析相关推荐
- Microsoft.Net框架程序设计学习笔记(11):类型构造器
除实例构造器外,CLR还支持类型构造器(又称静态构造器.类构造器.类型初始化器).类型构造器用于设置一个类型的初始状态.默认情况下,一个类型中没有定义类型构造器,只能手动定义.且类型构造器不能有任何参 ...
- hbase java框架_Hadoop学习笔记—15.HBase框架学习(基础实践篇)
一.HBase的安装配置 1.1 伪分布模式安装 伪分布模式安装即在一台计算机上部署HBase的各个角色,HMaster.HRegionServer以及ZooKeeper都在一台计算机上来模拟. 首先 ...
- Hadoop学习笔记—15.HBase框架学习(基础知识篇)
Hadoop学习笔记-15.HBase框架学习(基础知识篇) HBase是Apache Hadoop的数据库,能够对大型数据提供随机.实时的读写访问.HBase的目标是存储并处理大型的数据.HBase ...
- 条件分歧 java_FORTRAN-95程序设计学习笔记-资源下载人人文库网
<FORTRAN-95程序设计>学习笔记 FORTRAN 95程序设计学习笔记66RPG gg 目录 FORTRAN 95程序设计学习笔记1基础知识(基础.字符串.FORMAT.隐式.TY ...
- php mvc 路由,PHP MVC框架路由学习笔记
文章主要介绍了PHP MVC框架路由学习笔记的相关资料,需要的朋友可以参考下. 提到PHP开发web,自然离不开开发框架,开发框架为我们提供了灵活的开发方式,MVC层分离,业务解耦等... 第一篇先来 ...
- C语言程序设计学习笔记:P1-程序设计与C语言
本系列博客用于记录学习浙江大学翁恺老师的C语言程序设计,系列笔记链接如下: C语言程序设计学习笔记:P1-程序设计与C语言 C语言程序设计学习笔记:P2-计算 C语言程序设计学习笔记:P3-判断 C语 ...
- C++语言学习笔记15:Clean 垃圾清理插件
C++语言学习笔记15:Clean 垃圾清理插件 对话框 STET1 图片切换功能 导入位图资源 插入图片控件并修改属性 添加消息处理函数 step2 开发思路及类关系图 step3 添加控件及MFC ...
- JavaScript高级程序设计学习笔记(三)
分享一下第五章(引用类型)的笔记,内容比较多,我拆成了两部分,今天这部分是关于Object.Array.Date和RegExp类型的. 以下的笔记是书上一些我以前学习的时候,没有太重视的js基础知识, ...
- 面向对象程序设计·学习笔记(1/2)
面向对象程序设计·学习笔记(1/2) 前言 第1章 类与对象 1.1 用类制造对象 1.2 定义类 1.3 成员变量和成员函数 1.4 对象初始化 第2章 对象交互 2.1 对象交互 2.2 访问属性 ...
最新文章
- Docker镜像使用
- linux下如何查看系统和内核版本
- 详解程序包管理RPM
- Canvas实现文字粒子化,并且绕轴旋转(完善)
- c语言输入一个数存数组,//从键盘上输入若干整数,并将其存入数组中,并统计输入数据的个...
- 打通钉钉+WebHook:日志服务告警升级
- 家用电器用户行为分析与事件识别_数据产品指北:用户行为分析平台
- plsql中oracle定时任务日志,速掌握一个简单的Oracle定时任务
- debian重启ssh服务_VScode链接服务器并配置公钥SSH Keys
- 会员注册审核状态更新计算
- linux优麒麟iso镜像,国产优麒麟操作系统官方下载
- php rrd graph,使用lvs-rrd工具监控存储lvs状态信息
- CC2530 Hex文件解析
- STM32 HAL OTA 小白教程
- java id pid 递归,父子结构数据(id,pid)递归查询所有子id合集和父id合集
- 判断一个时间段是否经过了另一个时间段
- 图片滑块验证码的解决
- python常见的问题
- Spring中bean的含义
- 全球十大资质正规现货黄金交易平台排名榜单(最新版汇总)
热门文章
- 磁力mysql搜索_多功能搜索 搜索系统安装 小说 电影 磁力
- h710阵列卡支持最大硬盘_DELL服务器RAID磁盘阵列在线扩容(以H710P阵列卡为例)
- npm install packagename 安装失败的解决办法
- JAVA语言写的,用java语言写
- 外链引入css有哪些方式_快速收录的外链操作技巧
- 2014北科计算机原理试题答案,北科_计算机组成原理考题-A卷答案
- jquery 获取键值对中最大值_jQuery的AJAX发送数据键值对
- linux命令中的cp,Linux高级技术:关于cp命令中拷贝所有的写法
- 电大计算机一级b考试试题,电大计算机考试本科试题
- 罗盘时钟编码代码_安全研究 | 利用macOS Dock实现代码的持久化执行