一 发布者和订阅者

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

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

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

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

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

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

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

二 事件的使用

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. BZOJ1874 「一本通 6.7 练习 1」【一本通提高博弈论】取石子游戏

    「一本通 6.7 练习 1」取石子游戏 题目描述 小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游 ...

  2. 使用Huggingface在矩池云快速加载预训练模型和数据集

    作为NLP领域的著名框架,Huggingface(HF)为社区提供了众多好用的预训练模型和数据集.本文介绍了如何在矩池云使用Huggingface快速加载预训练模型和数据集. 1.环境 HF支持Pyt ...

  3. php命名空间粗解

    // 创建命名空间Articlenamespace Article;class Comment { } // 创建命名空间MessageBoardnamespace MessageBoard;clas ...

  4. SpringBoot定时任务 - 集成quartz实现定时任务(单实例和分布式两种方式)

    最为常用定时任务框架是Quartz,并且Spring也集成了Quartz的框架,Quartz不仅支持单实例方式还支持分布式方式.本文主要介绍Quartz,基础的Quartz的集成案例本,以及实现基于数 ...

  5. 内网渗透之Windows认证(二)

    title: 内网渗透之Windows认证(二) categories: 内网渗透 id: 6 key: 域渗透基础 description: Windows认证协议 abbrlink: d6b7 d ...

  6. SpringBoot定时任务 - 经典定时任务设计:时间轮(Timing Wheel)案例和原理

    Timer和ScheduledExecutorService是JDK内置的定时任务方案,而业内还有一个经典的定时任务的设计叫时间轮(Timing Wheel), Netty内部基于时间轮实现了一个Ha ...

  7. ETCD快速入门-01 ETCD概述

    1.ETCD概述 1.1 ETCD概述     etcd是一个高可用的分布式的键值对存储系统,常用做配置共享和服务发现.由CoreOS公司发起的一个开源项目,受到ZooKeeper与doozer启发而 ...

  8. 论文解读(g-U-Nets)《Graph U-Nets》

    论文信息 论文标题:Graph U-Nets论文作者:Hongyang Gao, Shuiwang Ji论文来源:2019,ICML论文地址:download 论文代码:download 1 Intr ...

  9. 解决使用 Eruda 绑定 dom 未在指定位置显示问题

    前言 开发项目中,使用到 Eruda 打印控制台信息显示 文档:https://github.com/liriliri/eruda 安装 Eruda npm install eruda --save ...

  10. Spring源码 02 项目搭建

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...