是什么

本文讨论类型中定义的最后一种成员:事件

定义了时间成员的类型允许类型通知其他对象发生了特定的事情。

具体的说,定义了时间成员的类型能提供以下功能:

  • 方法能登记它对事件的关注
  • 方法能注销它对事件的关注
  • 事件发生时,登记了的方法将收到通知

CLR事件模型以委托为基础。委托是调用回调方法的一种类型安全的方式。

怎么用

本文我们将通过一个小栗子来学习一下事件怎么使用:

假定有个bolg平台可以订阅文章,用户A、B、C可以通过订阅或取消订阅来接收或者不接受此平台的文章。即,我是管理员,我在blog上发了一篇文章,那么订阅blog的用户就可以收到这篇文章了。

下面我们来实现这个功能,顺便来学习下事件的使用:

第一步:定义类型来容纳所有需要发送给事件通知者的附加信息

约定:这种类型应该从System.EventArgs派生,而且类名以EventArgs结束。

internal class BlogEventArgs : EventArgs
{
private readonly String author, content;
private DateTime tdate; public BlogEventArgs(string author,string content,DateTime date)
{
this.author = author;
this.content = content;
this.tdate = date;
} public string Author { get { return author;} }
public string Content { get { return content; } }
public DateTime TDate { get { return tdate;} }
}

第二步:定义事件成员

约定:事件使用event关键字。每个事件成员要指定以下内容:可访问性标识符;委托类型;以及名称。

internal class BlogManager
{
public event EventHandler<BlogEventArgs> NewBlog;
}

第三步:定义负责引发事件的方法来通知事件的登记对象

约定:类要定义一个受保护的虚方法。引发事件时,类及其派生类中的代码回调用该方法。方法只接受一个参数,即BlogEventArgs对象

protected virtual void OnNewBlog(BlogEventArgs e)
{
EventHandler<BlogEventArgs> temp = Volatile.Read(ref NewBlog);
if (temp!=null)
{
temp(this, e);
}
}

关于为什么要像上边这样写,只能说这样是线程安全的方式引发事件,其他方式可能会有线程方面的问题。

第四步:定义方法将输入转化为期望事件

BlogManager中,调用WriteNewBlog来指出写了一篇新博客

public void WriteNewBlog(string author, string content, DateTime date)
{
BlogEventArgs e = new BlogEventArgs(author,content,date);
OnNewBlog(e);
}

第五步:设计侦听事件的类型

比如User类型想订阅或取消这个博客

internal sealed class Reader
{
public Reader(BlogManager blogManager)
{
blogManager.NewBlog += blogManager_NewBlog;
} void blogManager_NewBlog(object sender, BlogEventArgs e)
{
Console.WriteLine("读者已收到博客!");
Console.WriteLine("作者:{0},内容:{1},发表时间:{2}",e.Author,e.Content,e.TDate.ToShortTimeString());
} public void Unregister(BlogManager bmManager)
{
bmManager.NewBlog -= blogManager_NewBlog;
}
}

最后一步使用起来

class Program
{
static void Main(string[] args)
{
BlogManager bmManager = new BlogManager();
Reader readerA =new Reader(bmManager);
bmManager.WriteNewBlog("1号作者", "这是我的第一篇文章", DateTime.Now);
readerA.Unregister(bmManager);
bmManager.WriteNewBlog("1号作者", "这是我的第二篇文章,应该收不到", DateTime.Now);
Console.ReadKey();
}
}

运行


总结

根据书本《CLR via C#》的小栗子自己更改了一点,希望对你有帮助。

带你一步步的了解“C#事件”机制的更多相关文章

  1. ApplicationEvent事件机制源码分析

    <spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情> <服务网关zu ...

  2. Android自定义View的实现方法,带你一步步深入了解View(四)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17357967 不知不觉中,带你一步步深入了解View系列的文章已经写到第四篇了,回 ...

  3. Android视图状态及重绘流程分析,带你一步步深入了解View(三)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17045157 在前面一篇文章中,我带着大家一起从源码的层面上分析了视图的绘制流程, ...

  4. 【转】Android自定义View的实现方法,带你一步步深入了解View(四)

    原文网址: 转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17357967 不知不觉中,带你一步步深入了解View系列的文章已经写到 ...

  5. Android视图绘制流程完全解析,带你一步步深入了解View(二)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/16330267 在上一篇文章中,我带着大家一起剖析了一下LayoutInflater ...

  6. Android LayoutInflater原理分析,带你一步步深入了解View(一)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/12921889 有不少朋友跟我反应,都希望我可以写一篇关于View的文章,讲一讲Vi ...

  7. JavaScript 详说事件机制之冒泡、捕获、传播、委托

    DOM事件流(event  flow )存在三个阶段:事件捕获阶段.处于目标阶段.事件冒泡阶段. 事件捕获(event  capturing):通俗的理解就是,当鼠标点击或者触发dom事件时,浏览器会 ...

  8. 【初窥javascript奥秘之事件机制】论“点透”与“鬼点击”

    前言 最近好好的研究了一番移动设备的点击响应速度,期间不断的被自己坑,最后搞得焦头烂额,就是现在可能还有一些问题,但是过程中感觉自己成长不少, 最后居然感觉对javascript事件机制有了更好的认识 ...

  9. ExtJs的事件机制Event(学员总结)

    一.事件的三种绑定方式 1.HTML/DHTML 在标签中直接增加属性触发事件 [javascript] view plaincopy <script type="text/javas ...

随机推荐

  1. 相克军_Oracle体系_随堂笔记001-概述

    一.Oracle官方支持 1.在线官方文档 http://docs.oracle.com/ 2.metalink.oracle.com,如今已经改成:http://support.oracle.com ...

  2. HTML5+CSS3实现图片可倾斜摆放的动画相册效果

    先看看效果:其中鼠标悬浮在图片上会有动态效果图 直接上代码: css文件 @CHARSET "UTF-8"; *{ padding:0px; margin:0px; } div{ ...

  3. 在SQL Server里我们为什么需要意向锁(Intent Locks)?

    在1年前,我写了篇在SQL Server里为什么我们需要更新锁.今天我想继续这个讨论,谈下SQL Server里的意向锁,还有为什么需要它们. SQL Server里的锁层级 当我讨论SQL Serv ...

  4. 【那些年关于MyEclipse的快捷键大全】

    MyEclipse 快捷键1(CTRL)-------------------------------------Ctrl+1 快速修复Ctrl+D: 删除当前行 Ctrl+Q  定位到最后编辑的地方 ...

  5. Facebook Paper使用的第三方库

    Facebook Paper使用的第三方库 第三方库名 简介 链接 ACE code editor https://github.com/ajaxorg/ace Appirater 用户评分组件 ht ...

  6. EF Fluent API上

     什么是Fluent API? 官方答案:EF 中内嵌的约定将 POCO 类映射到表.但是,有时您无法或不想遵守这些约定,需要将实体映射到约定指示外的其他对象,所以Fluent API和注解都是一种方 ...

  7. web api中的RouteHandler

    ASP.NET MVC4中引入的Web API可以说是进行REST软件开发的利器(个人意见),但是最近在web form中混入web api时,发现一个问题:由于以前的web form项目中,使用到了 ...

  8. bzoj1191--匈牙利算法

    这道题一看就是求二分图最大匹配,不过需要注意的是答案需要前面所有题目都能答对,因为这里WA了无数次...... #include<iostream> #include<cstdio& ...

  9. DOM官方定义

    DOM Document Object Model 文档对象模型 DOM的官方定义:W3C的DOM,可以使程序或者脚本(JS或AS\JScript),动态的访问或者操作文档的内容.结构.样式. DOM ...

  10. jquery 文本/html/值

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...