C#中的EventHandler观察者模式详解

作者:细胞的理想 时间:2021-09-04 17:08:27 

C# 和 java 比较:java 中使用的是接口。C# 使用委托机制,可以用时 + 运算符进行注册,直接多播。而 java 中是一般是使用一个集合来保存观察者。

一、解释

发布者(Publisher)= 被观察者(Observable) = 事件源(java中的EventObject,C#中的sender)
订阅者(Subscriber)=观察者(Observer)= 接收者(java中继承EventLister,接口, 或Observer接口, C#由于委托机制,不需要继承接口,直接按EventHandler实现回调方法)

在发生其他类或对象关注的事情时,类或对象可通过事件通知它们。发送(或引发)事件的类称为“发行者”,接收(或处理)事件的类称为“订户”。在典型的 C# Windows 窗体或 Web 应用程序中,可订阅由控件(如按钮和列表框)引发的事件。可使用 Visual C# 集成开发环境 (IDE) 来浏览控件发布的事件,选择要处理的事件。IDE 会自动添加空事件处理程序方法和订阅事件的代码。

EventHandler 为 C# 中的预定义委托,专用于表示不生成数据的事件的事件的处理程序方法。

public delegate void EventHandler(Object sender, EventArgs e)

二、事件具有以下特点:

1. 发行者确定何时引发事件,订户确定执行何种操作来响应该事件。
2. 一个事件可以有多个订户。一个订户可处理来自多个发行者的多个事件。
3. 没有订户的事件永远不会被调用。
4. 事件通常用于通知用户操作(如:图形用户界面中的按钮单击或菜单选择操作)。
5. 如果一个事件有多个订户,当引发该事件时,会同步调用多个事件处理程序。要异步调用事件,请参见使用异步方式调用同步方法。
6. 可以利用事件同步线程。
7. 在 .NET Framework 类库中,事件是基于 EventHandler 委托和 EventArgs 基类的。

实例代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleAppEventArgs
{
   public class Program
   {
       public static void Main(string[] args)
       {
           Publisher pub = new Publisher();
           Subscriber sub1 = new Subscriber("sub1",pub);
           Subscriber sub2 = new Subscriber("sub2", pub);
           // 调用这个方法来产生事件
           pub.DoSomething();
           Console.WriteLine("Press Enter to close this window.");
           Console.ReadLine();
       }
   }
   /// <summary>
   /// 自定义一个事件类来保存事件信息
   /// </summary>
   public class CustomEventArgs : EventArgs
       public CustomEventArgs(string s)
       private string message;
       public string Message
           get { return message; }
           set { message = value; }
   /// 广播事儿件的类
   public class Publisher
       //使用EventHandler<T> 声明一个事件
       public event EventHandler<CustomEventArgs> RaiseCustomEvent;
       public void DoSomething()
           //DoSomething…………
           // 你也可以再触发事件前,执行一些其他的代码
           OnRaiseCustomEvent(new CustomEventArgs("Did something,hi 这是事件消息"));
       protected virtual void OnRaiseCustomEvent(CustomEventArgs  e)
           // 定义一个局部变量,已防止最后一个订阅者刚好在检查null后取消订阅
           EventHandler<CustomEventArgs> handler = RaiseCustomEvent;
           // 如果没有 订阅者(观察者), 委托对象将为null
           if (handler != null)
           {
               // 格式化事件消息中 的字符串
               e.Message += String.Format(" at {0}", DateTime.Now.ToString());
               // 这是最重要的一句。
               // 此时执行的  handler已经是一个多播委托(如果有多个订阅者或观察者注册)。
               // 既然是多播委托,就可以依次调用各个 回调函数 (既然是回调函数,实际的执行就由订阅者类决定)。
               //这里面传入一个this, 就代表 事件源(或发布者 或 被观察者 都一个意思)
               handler(this, e);
           }
   /// 用来注册事件的类
   public class Subscriber
       private string id;
       public Subscriber(string ID, Publisher pub)
           id = ID;//注册这个动作,应该有订阅者主动进行,并且可以再后期取消注册
           pub.RaiseCustomEvent += HandleCustomEvent;
       // 实现回调函数。在事件发生后,执行什么样的操作。这里只是简单的打印信息。
       void HandleCustomEvent(object sender, CustomEventArgs e)
           //这就是实际的操作。
           Console.WriteLine(id + " received this message: {0}", e.Message);
}

来源:https://www.cnblogs.com/xinhuawei/p/16008177.html

标签:C#,观察者模式
0
投稿

猜你喜欢

  • java中map与实体类的相互转换操作

    2023-03-14 01:42:35
  • java取两个字符串的最大交集

    2021-07-30 17:23:08
  • mybatis in foreach 双层嵌套问题

    2023-11-24 12:55:47
  • java实现MD5加密算法的实例代码

    2021-10-01 16:49:14
  • Java中StringUtils与CollectionUtils和ObjectUtil概念讲解

    2023-11-29 07:45:38
  • 详细聊聊SpringBoot中动态切换数据源的方法

    2023-11-24 04:07:49
  • SpringbootJPA分页 PageRequest过时的替代方法

    2022-03-10 11:53:13
  • Android四种数据存储的应用方式

    2023-07-25 05:01:06
  • JAVA集合框架Map特性及实例解析

    2021-06-05 02:23:39
  • Java 基于tcp协议实现文件上传

    2022-04-14 04:01:29
  • @SpringBootTest 注解报红问题及解决

    2022-08-14 23:24:51
  • Java 抽象类定义与方法实例详解

    2022-10-20 09:26:38
  • Springmvc模式上传和下载与enctype对比

    2022-11-08 09:14:17
  • c# 使用Task实现非阻塞式的I/O操作

    2023-07-21 23:27:39
  • java实现微信点餐申请微信退款

    2022-10-29 19:07:57
  • Java中的几种读取properties配置文件的方式

    2022-09-06 13:36:19
  • java中List接口与实现类介绍

    2022-11-17 02:54:40
  • Java中GUI工具包AWT和Swing用法介绍

    2022-02-06 09:02:35
  • Java几种常用的断言风格你怎么选

    2021-10-30 23:30:32
  • Java Swing实现让窗体居中显示的方法示例

    2023-11-06 02:59:07
  • asp之家 软件编程 m.aspxhome.com