深入理解事件(Event)

2023-05-16

前言

在前一篇文章中讲到了Event 发布与订阅(一) 里面用到了事件来实现一些发布与订阅,当时对事件及其委托理解的还不是太深入,可能在使用上有点捉急。这篇来好好讲讲事件,以及通过一些小DEMO来加深理解。可以说是让我重新理解了事件。

事件(Event)

事件:

定义了事件成员的类型允许类型(或类型的实例)通知其他对象发生特定的事情。例如:Button类提供了Click事件。应用程序中的一个或多个对象可接受关于该事件的通知,以便在Button被单击之后采取特定操作。

定义了事件成员的类型能提供以下功能。

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

CLR事件模型以委托为基础。委托时调用回调方法的一种类型安全的方式。对象凭借回调方法接受它们订阅的通知。

核心指南

想要实现一个事件,按照下面这四个步骤走:

1. 定义附加信息

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

这句话怎么理解呢,就以之前我们那个Car为例子。把它抽象出事件来看,我要定义一个开车通知事件,我想要知道的是 司机 和乘客都是谁:那么我们就定义一个长这样的:

using System;
using EventDemo.EventBus;

namespace EventDemo.CarDemo {
    public class CarNotificationEventData : EventData {
        private string _driverName;
        private string _passengerName;

        public CarNotificationEventData (string driver, string passenger) {
            _driverName = driver;
            _passengerName = passenger;
        }

        public string Driver { get { return _driverName; } }

        public string Passenger { get { return _passengerName; } }

        public DateTime NotifiDate { get { return DateTime.Now; } }
    }
}

那么我们就完成第一步了。

2. 定义事件成员

using System;
using System.Threading;

namespace EventDemo.CarDemo {
    //...

    public class CarManager {

        //定义一个 上车通知 事件 成员类型为 CarNoticationEventHandler
        public event CarNotificationEventHandler CarNotification;

        //...
}

CarNotification 是事件名称,事件成员的类型为 CarNotificationEventHandler。 这意味着 事件通知的 所有接收者都必须提供一个原型和 CarNotificationHandler 委托类匹配的回调方法。

CarNotificationHandler 的定义为:

    public delegate void CarNotificationEventHandler (CarNotificationEventData eventData);

3. 定义负责引发事件的方法来通知事件的登记对象

我在CarManager 中当然是定义一个 开车了 方法,来通知所有该事件的接受者说明车要开了。

 public void OnCarToRun (CarNotificationEventData carNotificationEventData) {

            //将委托字段的引用复制到一个临时变量中,出于线程安全的考虑
            CarNotificationEventHandler temp = Volatile.Read (ref CarNotification);

            if (temp != null) {
                temp (carNotificationEventData);
            }
        }

4. 定义方法将输入转化为期望事件

这就是步骤中的最后一步了,就是引发这个事件。在我们的场景中就是,把司机和乘客都叫上车,然后我们就发车了。

public void RunCar (Driver driver, Passenger passenger) {
            CarNotificationEventData carNotificationEventData = new CarNotificationEventData (driver.Name, passenger.Name);
            OnCarToRun (carNotificationEventData);
        }

把司机和乘客,添加到附加信息对象里面。然后就引发这个通知事件。


通过上面那四个步骤,应该对事件有个比较深入的了解,最后只需在各个事件的接受者里定义回调方法的处理就可以啦。

这里给出其中一个处理:

 public void DriverHandle (CarNotificationEventData carNotificationEventData) {
            Console.WriteLine ("Driver Hanlder---------");
            Console.WriteLine (carNotificationEventData.Driver + "\n" + carNotificationEventData.Passenger +
                "\n" + carNotificationEventData.NotifiDate);
        }

至此,整个事件的发布,接收和处理都已完毕。如有错误的地方,一起来讨论讨论。

转载于:https://www.cnblogs.com/xiyin/p/8848781.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深入理解事件(Event) 的相关文章

随机推荐

  • stm32系统定时器的作用

    stm32系统定时器的时钟源是那个 xff1f 系统定时器 xff0c 又称滴答定时器 xff0c 在使用OS xff08 操作系统 xff09 时 xff0c 其主要作用是为OS提供中断信号 xff0c 让OS执行任务调度 xff0c 当
  • 现场总线网络一般只实现了第1层(物理层)、第2层(数据链路层)、第7层(应用层)。

    现场总线网络一般只实现了第1层 物理层 第2层 数据链路层 第7层 应用层 因为现场总线通常只包括一个网段 xff0c 因此不需要第3层 传输层 和第4层 网络层 xff0c 也不需要第5层 会话层 第6层 描述层 的作用
  • 函数指针应用场景

    原文链接 xff1a https blog csdn net u011116085 article details 108106052 一个人C语言功底强不强 xff0c 不是看他写的代码注释够不够全 xff0c 代码逻辑够不够清晰 xff
  • STM32的Flash 具体是哪种flash?

    单片机内部的Flash应该是nor flash xff0c 因为 xff0c 在使用程序对Flash进行读写与擦除时 xff0c 都是要按一个页一个页的进行操作的 这与nor的特性是一样的 单片机中的程序是在Flash中运行的 xff0c
  • keil 无法直接生成bin文件 fromelf:格式转换工具

    fromelf exe转换工具的语法格式如下 xff1a fromelf span class token punctuation span options span class token punctuation span input f
  • jlink支持 国民MCU

    https www bilibili com read cv19376308 文件已保存到自己网盘
  • OSC_in 和 OSC_out 引脚 OSC32_IN和OSC32_OUT

    一般在单片机上都有 OSCin 和 OSCout 两个晶振接入端口 xff0c 我们可以用无源的晶振加上起震电容可以配合单片机是晶振起震 xff0c 为系统提供时钟源 顾名思义在OSCout端可以输出正弦波 xff0c 给别的器件提供振荡源
  • MDK 的jlink版本和jlink的驱动版本导致的问题 keil进入调试后只打了一个断点就提示断点太多

    查看MDK jlink版本 查看 jlink下载器的驱动版本 降低MDK jlink版本 调试起来很顺畅 降低版本方法 xff1a 重装keil 后 MDK jlink版本自动回到低版本 或者找到低版本的文件 直接替换segger文件夹
  • git 和 SVN 的区别 SVN搭建 分布式和非分布式

    https blog csdn net bruce 6 article details 38299677 ops request misc 61 257B 2522request 255Fid 2522 253A 2522168051782
  • 串口不仅要数据处理 还要对数据做容错处理

    如果接受到的数据不正确怎么办 排除硬件损坏的情况
  • Linux面试题总结(2022最新版)

    关于作者 x1f436 程序猿周周 短视频小厂BUG攻城狮 x1f93a 如果文章对你有帮助 xff0c 记得关注 点赞 收藏 xff0c 一键三连哦 xff0c 你的支持将成为我最大的动力 本文是 后端面试小册子 系列的第 5 篇文章 x
  • 10.dockerfile之WORKDIR指令

    一 WORKDIR指令说明 用来指定当前工作目录 xff08 或者称为当前目录 xff09 当使用相对目录的情况下 xff0c 采用上一个WORKDIR指定的目录作为基准 相当与cd 命令 xff0c 但不同的是指定了WORKDIR后 xf
  • 计算机系统层次存储结构

    问 xff1a 当前计算机系统一般会采用层次结构存储数据 xff0c 请介绍下典型计算机存储系统一般分为哪几个层次 xff0c 为什么采用分层存储数据能有效提高程序的执行效率 xff1f 所谓存储系统的层次结构 xff0c 就是把各种不同存
  • "R6002 floating point support not loaded"错误

    R6002 floating point support not loaded 错误 xff0c 在Debug模式下会弹出如下错误 xff1a floating point support not loaded 翻译为中文是 浮点指针支持未
  • docker 安装mysql:latest 问题

    背景 周末闲着没事 xff0c 然后想着在虚拟机用docker装个mysql吧 然后就开始安装了 正文 打开dockerhub com 在输入框输入mysql xff0c 选择mysql第一个 xff0c 进入后找到How to use t
  • TX2-刷机完成后安装程序ubuntu_linux命令&TX2学习总结

    Linux教程 菜鸟教程 xff1a http www runoob com linux linux tutorial html 认识linux ping命令 xff1a ping命令是常用的网络命令 ping网关 xff1a ping 1
  • 浅谈操作系统与内存

    浅谈操作系统与内存 对于计算机的发明 xff0c 相信大家都有耳闻那个占地面积按平米算的第一台计算机 在那个时候 xff0c CPU的资源是极其珍贵的 xff0c 随着这些年突飞猛进的发展 xff0c 一片指甲盖大小的民用级CPU一秒钟能执
  • linux系统编程之进程(八):守护进程详解及创建,daemon()使用

    一 xff0c 守护进程概述 Linux Daemon xff08 守护进程 xff09 是运行在后台的一种特殊进程 它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件 它不需要用户输入就能运行而且提供某种服务 xff0c 不
  • IMU&GPS融合定位::加速度计基本原理

    加速度计基本原理 核心 xff1a 牛顿第二定律 一 mems加速度计基本原理 加速度计基本结构如上图 xff0c 由上电容 中电容板 可移动 下电容板等组成 xff1b 当加速度达到一定值后 xff0c 中电容板会移动 xff0c 与上
  • 深入理解事件(Event)

    前言 在前一篇文章中讲到了Event 发布与订阅 一 里面用到了事件来实现一些发布与订阅 xff0c 当时对事件及其委托理解的还不是太深入 xff0c 可能在使用上有点捉急 这篇来好好讲讲事件 xff0c 以及通过一些小DEMO来加深理解