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

c#事件案例与分析

using System;
using System.Collections.Generic;

namespace EventExample
{
    // 定义事件数据
    public class DataReceivedEventArgs : EventArgs
    {
        public string Data { get; }

        public DataReceivedEventArgs(string data)
        {
            Data = data;
        }
    }

    // 发布者类
    public class Publisher
    {
        // 定义事件
        public event EventHandler<DataReceivedEventArgs> DataReceived;

        // 模拟数据接收
        public void ReceiveData(string data)
        {
            Console.WriteLine("Publisher: Receiving data...");
            OnDataReceived(data);
        }

        // 触发事件
        protected virtual void OnDataReceived(string data)
        {
            try
            {
                DataReceived?.Invoke(this, new DataReceivedEventArgs(data));
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error while notifying subscribers: {ex.Message}");
            }
        }
    }

    // 订阅者类
    public class Subscriber
    {
        private readonly string _name;

        public Subscriber(string name)
        {
            _name = name;
        }

        // 处理事件的方法
        public void OnDataReceived(object sender, DataReceivedEventArgs e)
        {
            if (e == null || string.IsNullOrEmpty(e.Data))
            {
                Console.WriteLine($"{_name} received empty data.");
                return;
            }
            Console.WriteLine($"{_name} received data: {e.Data}");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // 创建发布者
            Publisher publisher = new Publisher();

            // 创建订阅者
            Subscriber subscriber1 = new Subscriber("Subscriber 1");
            Subscriber subscriber2 = new Subscriber("Subscriber 2");

            // 订阅事件
            publisher.DataReceived += subscriber1.OnDataReceived;
            publisher.DataReceived += subscriber2.OnDataReceived;

            // 模拟接收数据
            publisher.ReceiveData("Hello, World!");

            // 取消订阅
            publisher.DataReceived -= subscriber1.OnDataReceived;

            // 再次模拟接收数据
            publisher.ReceiveData("Goodbye, World!");

            Console.ReadLine();
        }
    }
}

1. 事件定义
首先,在 Publisher 类中定义了一个事件 DataReceived,它的类型是 EventHandler<DataReceivedEventArgs>。这意味着该事件可以传递一个 DataReceivedEventArgs 类型的参数,通常用于包含与事件相关的数据。

public event EventHandler<DataReceivedEventArgs> DataReceived;
2. 事件处理方法
在 Subscriber 类中定义了一个方法 OnDataReceived,这个方法将会作为事件处理程序(event handler)来处理 DataReceived 事件。当事件被触发时,OnDataReceived 方法会被调用,并接收事件的发出者(sender)和事件数据(DataReceivedEventArgs)作为参数。

public void OnDataReceived(object sender, DataReceivedEventArgs e)
{
    // 处理事件
}
3. 订阅事件
publisher.DataReceived += subscriber1.OnDataReceived; 这行代码的作用是将 subscriber1 的 OnDataReceived 方法注册为 publisher 的 DataReceived 事件的处理程序。具体的执行逻辑如下:

事件订阅:使用 += 运算符将 subscriber1.OnDataReceived 方法添加到 DataReceived 事件的事件处理列表中。这意味着,当 DataReceived 事件被触发时,所有订阅了该事件的方法(包括 subscriber1.OnDataReceived)都会被调用。
4. 事件触发
在 Publisher 类中,有一个方法 OnDataReceived,它会触发 DataReceived 事件。这个方法会检查是否有订阅者,并调用它们的事件处理方法:

protected virtual void OnDataReceived(string data)
{
    DataReceived?.Invoke(this, new DataReceivedEventArgs(data));
}
5. 事件处理
当调用 publisher.ReceiveData("Hello, World!"); 时,会触发 DataReceived 事件,导致 OnDataReceived 方法被调用。所有订阅了 DataReceived 事件的方法都会被执行。在这种情况下,subscriber1.OnDataReceived 将会被调用,并传入 publisher 作为 sender 和包含数据 "Hello, World!" 的 DataReceivedEventArgs 对象。

总结
publisher.DataReceived += subscriber1.OnDataReceived; 是将 subscriber1 的 OnDataReceived 方法注册为事件处理程序的过程。
当 DataReceived 事件被触发时,所有注册的处理程序(包括 subscriber1.OnDataReceived)会被依次调用,处理相关的事件数据。
这种机制使得发布者(Publisher)和订阅者(Subscriber)之间实现了松耦合的关系,发布者不需要知道具体的订阅者,只需触发事件即可。


http://www.kler.cn/a/578056.html

相关文章:

  • 2025年Linux 安全与运维指南
  • 机试题——微服务群组
  • React基础之useCallback
  • LeetCode刷题实战:删除字符串中的所有相邻重复项(栈的经典应用)
  • 2025-03-07 学习记录--C/C++-PTA 习题8-1 拆分实数的整数与小数部分
  • 哪些培训课程适合学习PostgreSQL中级认证知识?
  • CS144 Lab Checkpoint 6: building an IP router
  • 华为欧拉系统 Tomcat 安装详解
  • linux 内网下载 yum 依赖问题
  • ‌CentOS 7.9 安装 Docker 步骤
  • leetcode454 四数相加
  • flutter的debounce_throttle插件使用
  • 进程、线程、锁面试前复习(尽力局)
  • Myslq表的内外连接
  • Python项目-基于Django的在线教育平台开发
  • 【音视频】ffplay简单过滤器
  • 【算法】010、合并两个有序链表
  • 使用 display: flex 实现动态布局:每行两个 item,单数时最后一个占满整行
  • Redis数据结构——list
  • nacos和Eureka的学习