当前位置: 首页 > news >正文

浅谈C#事件

一、基本介绍

        事件是一种特殊的多播委托,用于实现发布-订阅模式。事件允许对象在发生特定情况时通知其他对象。事件的发布者(也称为事件源)定义事件,并在适当的时机触发事件;事件的订阅者(也称为事件处理程序)订阅事件,并在事件被触发时接收通知。

事件的基本使用

定义事件:在类中定义一个事件,通常使用 event 关键字。

public class Publisher
{// 定义一个事件public event EventHandler MyEvent;// 触发事件的方法protected virtual void OnMyEvent(EventArgs e){MyEvent?.Invoke(this, e);}// 调用该方法来触发事件public void DoSomething(){// 执行某些操作...OnMyEvent(EventArgs.Empty);}
}

订阅事件:在另一个类中订阅事件。

public class Subscriber
{public void Subscribe(Publisher publisher){publisher.MyEvent += OnPublisherEvent;}private void OnPublisherEvent(object sender, EventArgs e){Console.WriteLine("Publisher raised an event!");}
}

取消订阅事件:如果不再需要接收事件通知,可以取消订阅。

public void Unsubscribe(Publisher publisher)
{publisher.MyEvent -= OnPublisherEvent;
}

事件的触发

事件本身不是方法,而是一种特殊的多播委托。在类内部,通常会有一个受保护的方法来触发事件,这个方法会调用事件委托。使用 ?. 操作符可以确保在事件没有订阅者时不会引发空引用异常。

事件的安全性

  • 线程安全:在多线程环境中,事件的触发应该考虑线程安全。可以使用 lock 语句来同步对事件委托的访问。
  • 避免空引用异常:使用 ?.Invoke 来避免在没有订阅者时引发空引用异常。

事件的高级特性

  • 自定义事件参数:可以定义自定义的事件参数类来传递更复杂的数据。
  • 弱事件模式:为了减少内存泄漏的风险,可以使用弱事件模式。在这种模式下,事件订阅者持有事件源的弱引用。

示例:使用自定义事件参数

public class Publisher
{public event EventHandler<MyEventArgs> MyEvent;protected virtual void OnMyEvent(MyEventArgs e){MyEvent?.Invoke(this, e);}public void DoSomething(string message){OnMyEvent(new MyEventArgs { Message = message });}
}public class MyEventArgs : EventArgs
{public string Message { get; set; }
}public class Subscriber
{public void Subscribe(Publisher publisher){publisher.MyEvent += OnPublisherEvent;}private void OnPublisherEvent(object sender, MyEventArgs e){Console.WriteLine($"Publisher raised an event with message: {e.Message}");}
}

在这个示例中,MyEventArgs 是一个自定义的事件参数类,它允许事件处理程序接收额外的信息。事件的发布者在触发事件时创建并传递这个自定义事件参数的实例。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • sqli-libs第四关详解
  • Python脚本阿里云服务监控脚本
  • 考研--数学(相关公式)
  • 【王树森】BERT:预训练Transformer模型(个人向笔记)
  • Pinterest账号被封?试试这几种解封方法
  • 排序算法之堆排序详细解读(附带Java代码解读)
  • 【比较】数据字节串/字串比较指令 (CMPSB/CMPSW),数据字节串/字串检索指令(SCASB/SCASW)的区别
  • 实战项目:俄罗斯方块(二)
  • 鸿蒙OpenHarmony、HarmonyOS、HarmonyOS NEXT的区别
  • 直播行业的未来:南昌络喆科技有限公司的创新无人直播项目!
  • The Power of Scale for Parameter-Efficient Prompt Tuning
  • Hive锁表、hive查询表是否被锁、hive解锁表
  • 数据结构之 “单链表“
  • MAC环境导出项目的目录结构
  • 【iOS】折叠cell
  • 「面试题」如何实现一个圣杯布局?
  • 07.Android之多媒体问题
  • Android Studio:GIT提交项目到远程仓库
  • Hibernate最全面试题
  • HTTP那些事
  • iOS编译提示和导航提示
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • java正则表式的使用
  • Js基础知识(四) - js运行原理与机制
  • ReactNative开发常用的三方模块
  • SQLServer之创建数据库快照
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 王永庆:技术创新改变教育未来
  • 赢得Docker挑战最佳实践
  • 智能网联汽车信息安全
  • hi-nginx-1.3.4编译安装
  • ionic异常记录
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​人工智能书单(数学基础篇)
  • (1)(1.13) SiK无线电高级配置(六)
  • (STM32笔记)九、RCC时钟树与时钟 第二部分
  • (搬运以学习)flask 上下文的实现
  • (带教程)商业版SEO关键词按天计费系统:关键词排名优化、代理服务、手机自适应及搭建教程
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (六)激光线扫描-三维重建
  • (四)事件系统
  • (算法)硬币问题
  • (微服务实战)预付卡平台支付交易系统卡充值业务流程设计
  • (转)【Hibernate总结系列】使用举例
  • (转)拼包函数及网络封包的异常处理(含代码)
  • .NET Core 版本不支持的问题
  • .NET(C#、VB)APP开发——Smobiler平台控件介绍:Bluetooth组件
  • .NET业务框架的构建
  • :=
  • ?
  • [ solr入门 ] - 利用solrJ进行检索
  • [Android Pro] android 混淆文件project.properties和proguard-project.txt
  • [C++]类和对象【上篇】
  • [C++初阶]list的模拟实现
  • [CC2642R1][VSCODE+Embedded IDE+IAR Build+Cortex-Debug] TI CC2642R1基于VsCode的开发环境