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

C# 事件(Event)详解及实战示例

在 C# 中,**事件(Event)**是一种非常重要的机制,它允许一个对象在状态发生变化时通知其他对象,而无需知道这些对象的具体实现。事件广泛应用于 GUI 编程、系统通知、业务逻辑处理以及线程间通信等场景,是实现观察者模式(Observer Pattern)的核心工具。

本文将系统讲解 C# 事件的概念、使用方式,并结合实例演示实际应用。


事件的基本概念

可以把事件理解为“信号”或“通知”,通常由某个操作触发,例如:

  • 用户操作:点击按钮、键盘输入、鼠标移动等
  • 系统操作:定时器到期、中断触发、业务流程完成等

事件机制允许发布者(Publisher)将事件通知给订阅者(Subscriber),订阅者在事件触发时执行相应的处理逻辑。C# 中事件和委托密不可分,事件实际上是封装了委托的一种机制。


事件的核心流程

使用 C# 事件主要包括四个步骤:

  1. 声明委托
    委托定义了事件处理函数的签名。

    publicdelegatevoidNotifyEventHandler(objectsender,EventArgse);
  2. 声明事件
    使用event关键字声明事件,并指定委托类型。

    publiceventNotifyEventHandlerProcessCompleted;
  3. 触发事件
    在合适的时机调用事件,通知所有订阅者。

    protectedvirtualvoidOnProcessCompleted(EventArgse){ProcessCompleted?.Invoke(this,e);}
  4. 订阅和取消订阅事件
    其他类通过+=-=运算符来订阅或取消订阅事件。

    process.ProcessCompleted+=Process_ProcessCompleted;

发布者与订阅者

  • 发布者(Publisher)
    包含事件和触发逻辑的类。当事件发生时,它调用事件通知订阅者。

  • 订阅者(Subscriber)
    提供事件处理函数的类。订阅者注册事件后,在事件触发时执行相应操作。

这种模式称为发布-订阅模式(Publisher-Subscriber Pattern)


简单示例:业务流程事件

usingSystem;namespaceEventDemo{publicdelegatevoidNotifyEventHandler(objectsender,EventArgse);publicclassProcessBusinessLogic{publiceventNotifyEventHandlerProcessCompleted;protectedvirtualvoidOnProcessCompleted(EventArgse){ProcessCompleted?.Invoke(this,e);}publicvoidStartProcess(){Console.WriteLine("Process Started!");// 模拟业务逻辑OnProcessCompleted(EventArgs.Empty);}}publicclassEventSubscriber{publicvoidSubscribe(ProcessBusinessLogicprocess){process.ProcessCompleted+=Process_ProcessCompleted;}privatevoidProcess_ProcessCompleted(objectsender,EventArgse){Console.WriteLine("Process Completed!");}}classProgram{staticvoidMain(){ProcessBusinessLogicprocess=newProcessBusinessLogic();EventSubscribersubscriber=newEventSubscriber();subscriber.Subscribe(process);process.StartProcess();}}}

运行结果:

Process Started! Process Completed!

实战示例:热水锅炉日志记录系统

通过一个模拟热水锅炉的系统,展示事件在实际业务中的应用:

usingSystem;usingSystem.IO;classBoiler{publicintTemp{get;privateset;}publicintPressure{get;privateset;}publicBoiler(inttemp,intpressure){Temp=temp;Pressure=pressure;}}classBoilerEventPublisher{publicdelegatevoidBoilerLogHandler(stringmessage);publiceventBoilerLogHandlerBoilerEventLog;publicvoidLogBoilerStatus(){Boilerboiler=newBoiler(100,12);stringremarks=(boiler.Temp<80||boiler.Temp>150||boiler.Pressure<12||boiler.Pressure>15)?"Need Maintenance":"O.K.";BoilerEventLog?.Invoke($"Logging Info:\nTemperature:{boiler.Temp}\nPressure:{boiler.Pressure}\nMessage:{remarks}");}}classBoilerLogger:IDisposable{privatereadonlyStreamWriter_writer;publicBoilerLogger(stringfilePath){_writer=newStreamWriter(filePath,append:true);}publicvoidLogToFile(stringinfo)=>_writer.WriteLine(info);publicvoidDispose()=>_writer?.Close();}classProgram{staticvoidLoggerToConsole(stringinfo)=>Console.WriteLine(info);staticvoidMain(){usingvarfileLogger=newBoilerLogger("boiler.txt");varboilerEvent=newBoilerEventPublisher();// 订阅事件boilerEvent.BoilerEventLog+=LoggerToConsole;boilerEvent.BoilerEventLog+=fileLogger.LogToFile;// 触发事件boilerEvent.LogBoilerStatus();}}

运行效果:

Logging Info: Temperature: 100 Pressure: 12 Message: O.K.

日志同时也写入boiler.txt文件,实现事件驱动的多通道日志记录。


使用事件的注意事项

  • 封装性:外部类只能订阅或取消订阅事件,不能直接触发事件,保证发布者控制权。
  • 线程安全:在多线程环境中触发事件,使用?.Invoke或委托拷贝,避免空引用或竞态条件。
  • 自定义事件参数:当需要传递更多信息时,可继承EventArgs创建自定义事件参数类,而不仅仅使用EventArgs.Empty

总结

C# 事件是封装了委托的通知机制,非常适合实现发布-订阅模式。通过事件,可以让对象在状态变化时通知多个订阅者,实现业务逻辑解耦。使用事件的基本流程:声明委托 → 声明事件 → 触发事件 → 订阅事件。事件不仅适用于 UI 操作,还能用于后台业务逻辑、日志记录、线程通信等场景。掌握事件机制及注意事项,你的 C# 程序将更加灵活、可扩展且易于维护。

http://www.jsqmd.com/news/466646/

相关文章:

  • Zynq QSPI Flash烧写全流程:从FSBL调试到BOOT.bin生成(避坑指南)
  • 4大技术突破:pycatia实现CATIA自动化的进阶指南
  • 利用快马平台快速构建java八股文学习应用原型
  • QGC二次开发实战:从源码下载到成功编译的完整记录(基于Stable_V4.2分支)
  • 天津枳强税务师事务所审计服务价格多少,性价比高不高 - 工业品牌热点
  • DFSDM数字滤波器深度解析:Σ-Δ调制信号处理与工程实践
  • CATIA自动化技术突破与实战指南:用Python重塑机械设计流程
  • Pi0效果展示:不同语义粒度指令对比——‘抓取’vs‘轻柔抓取红色方块’
  • MGeo门址结构化模型效果展示:ASA对抗训练显著提升‘XX村XX组XX户’类农村地址解析率
  • 分析北京睿智宏达家政服务舒适性好吗,它在行业内权威靠谱吗? - mypinpai
  • 手把手教你:在麒麟4.0.2(aarch64)上从源码编译curl8.5.0完整流程
  • 3步解锁音乐新体验:智能歌词工具的革命性突破
  • VideoAgentTrek-ScreenFilter快速上手:基于Docker的本地开发环境部署
  • Qwen3-TTS声音克隆效果:中文播客主持人音色克隆+英语配音迁移
  • LCD压合技术中的常见问题与解决方案:从导电粒子检测到压合强度控制
  • github小白入门指南:借助快马ai轻松实现你的第一个开源小应用
  • 使用yz-女生-角色扮演-造相Z-Turbo创建虚拟偶像:从形象设计到直播应用
  • Avalonia样式编写指南:如何像写CSS一样美化你的UI
  • 6G网络要来了,可是手机将迎来全面涨价
  • Git-RSCLIP与区块链结合的图像版权保护系统
  • 使用 MySQL 从 JSON 字符串提取数据
  • 4步打造专属暗黑2体验:d2s-editor存档定制全指南
  • Youtu-VL-4B-Instruct实战体验:上传图片提问,AI帮你详细描述
  • TabPFN模型下载体验优化指南:从警告抑制到多环境适配
  • 使用Unity3D开发口罩检测AR应用
  • 3大革新功能提升英雄联盟体验:League-Toolkit实战指南
  • why color in American?
  • 造相-Z-Image部署教程:Docker容器资源限制与显存分配最佳实践
  • 突破飞控性能瓶颈:Betaflight 2025.12的Azure RTOS架构创新实践
  • 图文翻译神器!translategemma-27b-it本地部署保姆级教程