一 发布者和订阅者

很多时候都有这种需求,当一个特定的程序事件发生时,程序的其他部分可以得到该事件已经发生的通知。

发布者/订阅者模式可以满足这种需求。

发布者:发布某个事件的类或结构,其他类可以在该事件发生时得到通知。

订阅者:注册并在事件发生时得到通知的类或结构。

事件处理程序:由订阅者注册到事件的方法,在发布者触发事件时执行。

触发事件:当事件触发时,所有注册到它的方法会被依次调用。

事件包含了一个私有的委托,事件提供了其私有的委托的结构化访问。

二 事件的使用

2.1 声明事件

class Incrementer
{
//声明一个CoutedADozen事件
public event EventHandler CountedADozen;
}

事件声明在一个类中,通过event关键字声明。

需要委托类型的名称(如:EventHandler),任何注册到事件的处理程序都必须与委托相匹配。

事件是成员,事件成员被隐式自动初始为null。

BCL声明了一个叫做EventHandler的委托,专门用于系统事件。

2.2 订阅事件

订阅者向事件添加事件处理程序。对于一个要添加到事件的处理程序来说,它必须具有与事件的委托相同的返回类型和签名。

订阅事件的几种形式:

//订阅事件的几种形式
incrementer.CountedADozen += IncrementDozensCount; //方法引用形式,实例方法
incrementer.CountedADozen += ClassB.CountHandlerB; //方法引用形式,静态方法
incrementer.CountedADozen += new EventHandler(cc.CountHandleC); //委托形式

和委托一样,也可以使用匿名方法和Lambda表达式来添加事件处理程序。

2.3 触发事件

下附简单的包含发布者和订阅者程序。

delegate void Handler();    //声明委托

class Incrementer
{
public event Handler CountedADozen;  //声明事件并发布 public void DoCount()
{
for (int i = 0; i < 100; i++)
{
if (i % 10 == 0)
{
if (CountedADozen != null)
{
CountedADozen();  //先判断事件是否为null,再触发事件
}
// 简化事件触发语法: CountedADozen?.Invoke();
}
}
}
} class Dozens
{
public int DozensCount { get; private set; } public Dozens(Incrementer incrementer)
{
incrementer.CountedADozen += IncrementDozensCount;  //订阅事件
} //事件处理程序
private void IncrementDozensCount()
{
DozensCount++;
}
} class Program
{
static void Main(string[] args)
{
var incrementer = new Incrementer();
var dozens = new Dozens(incrementer); incrementer.DoCount();
Console.WriteLine($"Number of dozens = {dozens.DozensCount}");
Console.Read();
}
}

2.4 移除事件处理程序

incrementer.CountedADozen -= IncrementDozensCount;  //移除事件处理程序

如果一个处理程序向事件注册了多次,那么当执行命令移除处理程序时,将只移除列表中该处理程序的最后一个实例。

C#-10 事件的更多相关文章

  1. nodeJS学习(10) --- 事件模块

    转载:http://www.cnblogs.com/zhongweiv/p/nodejs_events.html 目录 简介及资料 事件常用函数及使用 emitter.on(event, listen ...

  2. android 10 事件

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layo ...

  3. 经典线程同步 事件Event

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇 一个经典的多线程同步问题> <秒杀多线程第五篇 经典线程同步关键段CS> 上一篇中使用关键段来解决经典的多线程同步互斥问题 ...

  4. 委托和事件[delegate and event]_C#

    委托和事件: 1. 委托:一个能够表示方法的数据类型:它将方法作为对象封装起来,允许在运行时间接地绑定一个方法调用. 2. 声明委托数据类型: public delegate  bool Greate ...

  5. 多线程面试题系列(6):经典线程同步 事件Event

    上一篇中使用关键段来解决经典的多线程同步互斥问题,由于关键段的"线程所有权"特性所以关键段只能用于线程的互斥而不能用于同步.本篇介绍用事件Event来尝试解决这个线程同步问题.首先 ...

  6. WPF 学习笔记 路由事件

    1. 可传递的消息: WPF的UI是由布局组建和控件构成的树形结构,当这棵树上的某个节点激发出某个事件时,程序员可以选择以传统的直接事件模式让响应者来响应之,也可以让这个事件在UI组件树沿着一定的方向 ...

  7. 浏览器根对象window之事件

    1. [事件]动画 onanimationstart onanimationend onanimationiteration onwebkitanimationend onwebkitanimatio ...

  8. 转--- 秒杀多线程第六篇 经典线程同步 事件Event

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇 一个经典的多线程同步问题> <秒杀多线程第五篇 经典线程同步关键段CS> 上一篇中使用关键段来解决经典的多线程同步互斥问题 ...

  9. 《锋利的jQuery》读书笔记(DOM+事件)

    前阵子买了一批书,就从锋利的jQuery看起吧,书中一些太过常规以及没有强记必要性的操作就不记录了. 1.DOM加载后执行JS $(document).ready(function(){ //.... ...

随机推荐

  1. 开源一个自动整理B站UWP客户端软件进行批量下载的视频文件的小工具BiliVideosReoganizeHelper​

    ​ 大家都知道B站是一个很受欢迎的视频学习网站,上面有很多无私的up主上传了大量优秀的教学视频,在此向B站致敬,向广大UP主致敬. 有时,我们需要下载收藏一些视频,以防止以后找不到了.那么我们可以用B ...

  2. SpringBoot定时任务 - 什么是ElasticJob?如何集成ElasticJob实现分布式任务调度?

    前文展示quartz实现基于数据库的分布式任务管理和job生命周期的控制,那在分布式场景下如何解决弹性调度.资源管控.以及作业治理等呢?针对这些功能前当当团队开发了ElasticJob,2020 年 ...

  3. SP6779 GSS7 - Can you answer these queries VII(线段树,树链剖分)

    水题,只是坑点多,\(tag\)为\(0\)时可能也要\(pushdown\),所以要\(bool\)标记是否需要.最后树链剖分询问时注意线段有向!!! #include <cstring> ...

  4. PySpark 大数据处理

    本文主要介绍Spark的一些基本算子,PySpark及Spark SQL 的使用方法. 虽然我从2014年就开始接触Spark,但几年来一直没有真正地学以致用,时间一久便忘了如何使用,直到在工作中用到 ...

  5. Go语言 WaitGroup 详解

    你必须非常努力,才能看起来毫不费力! 微信搜索公众号[ 漫漫Coding路 ],一起From Zero To Hero ! 前言 在前面的文章中,我们使用过 WaitGroup 进行任务编排,Go语言 ...

  6. DBPack 限流熔断功能发布说明

    上周我们发布了 v0.4.0 版本,增加了限流熔断功能,现对这两个功能做如下说明. 限流 DBPack 限流熔断功能通过 filter 实现.要设置限流规则,首先要定义 RateLimitFilter ...

  7. ENSP NE40E 报错(NE1启动操作超时,请检查与服务器链接后重试!)

    前言:某网友淘宝找我咨询NE40E启动失败的问题,事后我整理的处理过程,供各位同行参考. 系统版本:windows 10 软件版本: ENSP:V100R003C00 virtual BOX:5.2. ...

  8. Taurus.MVC 微服务框架 入门开发教程:项目集成:5、统一的日志管理。

    系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 本系列第一篇:Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单 ...

  9. Docker 拉取Nginx镜像 和运行

    Docker 镜像拉取 docker pull [OPTIONS] NAME[:TAG|@DIGEST] 镜像拉取命令 OPTIONS说明: -a :拉取所有 tagged 镜像 --disable- ...

  10. 自定义View3-水波纹扩散(仿支付宝咻一咻)实现代码、思想

    PS:自定义view篇-水波纹实现 效果:水波纹扩散 场景:雷达.按钮点击效果.搜索等 实现:先上效果图,之前记得支付宝有一个咻一咻,当时就是水波纹效果,实现起来一共两步,第一画内圆,第二画多个外圆, ...