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 基类的。

下面的示例演示了上述步骤,它将自定义 EventArgs 类和 EventHandler<T> 用作事件类型。

namespace ConsoleApplication2
{
using System;
using System.Collections.Generic; // 自定义一个事件类来保存事件信息
public class CustomEventArgs : EventArgs
{
public CustomEventArgs(string s)
{
message = s;
}
private string message; public string Message
{
get { return message; }
set { message = value; }
}
} // 广播事件的类
class Publisher
{
// 使用 EventHandler<T> 声明一个事件
public event EventHandler<CustomEventArgs> RaiseCustomEvent;
//这个方法是做了一些事情。 然后触发一个事件。
public void DoSomething()
{
//DoSomething…………
// 你也可以再触发事件前,执行一些其他的代码
OnRaiseCustomEvent(new CustomEventArgs("Did something,hi 这是事件消息"));
}
//使用虚方法,让子类可以重写。 to allow derived classes to override the event invocation behavior
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);
}
}
} //用来注册事件的类
class Subscriber
{
private string id;
public Subscriber(string ID, Publisher pub)
{
id = ID;
// 注册事件,使用C#2.0语法
//注册这个动作,应该有订阅者主动进行,并且可以再后期取消注册
pub.RaiseCustomEvent += HandleCustomEvent;
}
// 实现回调函数。 在事件发生后,执行什么样的操作。这里只是简单的打印信息。
void HandleCustomEvent(object sender, CustomEventArgs e)
{
//这就是实际的操作。
Console.WriteLine(id + " received this message: {0}", e.Message);
}
} class Class1
{
static void Main(string[] args)
{
Publisher pub = new Publisher();
Subscriber sub1 = new Subscriber("sub1", pub);
Subscriber sub2 = new Subscriber("sub2", pub);
// 调用这个方法来产生事件
pub.DoSomething();
// Keep the console window open
Console.WriteLine("Press Enter to close this window.");
Console.ReadLine();
}
}
}

C# EventHandler观察者模式的更多相关文章

  1. C# ~ 从 委托事件 到 观察者模式 - Observer

    委托和事件的部分基础知识可参见 C#/.NET 基础学习 之 [委托-事件] 部分: 参考 [1]. 初识事件 到 自定义事件: [2]. 从类型不安全的委托 到 类型安全的事件: [3]. 函数指针 ...

  2. C#固定时间执行指定事件(观察者模式+异步委托)

    最近有个项目需要每天固定的时间去执行指定的事件,发现网上关于这样的文章比较少,而且比较散.通过学习了几篇文章后终于实现了这个功能,在此也特别感谢这些文章的作者们,这也是我第一次在园子里面发文章,望多指 ...

  3. C# 委托和事件 与 观察者模式(发布-订阅模式)讲解 by天命

    使用面向对象的思想 用c#控制台代码模拟猫抓老鼠 我们先来分析一下猫抓老鼠的过程 1.猫叫了 2.所有老鼠听到叫声,知道是哪只猫来了 3.老鼠们逃跑,边逃边喊:"xx猫来了,快跑啊!我是老鼠 ...

  4. 设计模式学习之观察者模式(Observer,行为型模式)(7)

    1.观察者模式又叫做发布-订阅模式. 2.观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 3 ...

  5. C#设计模式——观察者模式(Observer Pattern)1

    一.概述在软件设计工作中会存在对象之间的依赖关系,当某一对象发生变化时,所有依赖它的对象都需要得到通知.如果设计的不好,很容易造成对象之间的耦合度太高,难以应对变化.使用观察者模式可以降低对象之间的依 ...

  6. C#设计模式——观察者模式(Observer Pattern)

    一.概述在软件设计工作中会存在对象之间的依赖关系,当某一对象发生变化时,所有依赖它的对象都需要得到通知.如果设计的不好,很容易造成对象之间的耦合度太高,难以应对变化.使用观察者模式可以降低对象之间的依 ...

  7. Unity C# 多态 委托 事件 匿名委托 Lambda表达式 观察者模式 .NET 框架中的委托和事件

    一.多态 里氏替换原则: 任何能用基类的地方,可以用子类代替,反过来不行.子类能够在基类的基础上增加新的行为.面向对象设计的基本原则之一. 开放封闭原则: 对扩展开放,意味着有新的需求或变化时,可以对 ...

  8. 委托、事件、Observer观察者模式的使用解析二

    一.设计模式-Observer观察者模式 Observer设计模式是为了定义对象间的一种一对多的依赖关系,以便于当一个对象的状态改变时,其他依赖于它的对象会被自动告知并更新.Observer模式是一种 ...

  9. C#学习笔记-观察者模式

    题目1:几个同事为了在上班期间偷偷看休息,做点其他的事情,就和小秘偷偷联系了一下,如果老板回来了,就麻烦小秘偷偷通知一声,这样方便大家及时变更自己的工作状态. 分析: 根据题目分析,首先明确,肯定会有 ...

随机推荐

  1. window开机启动

    C:\Users\sunyues\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup 再次文件夹下写脚本就可 @echo off ...

  2. mybatis框架,使用foreach实现复杂结果的查询--循环List集合方式

    需求,根据用户角色列表  查询用户列表信息 之前我们传入的参数是Array,一个数组的形式,现在我们传入的是一个List集合,其他条件没有变化. /** * 需求:传入指定的用户角色,用户角色有1-n ...

  3. JDOJ 2175: 忠诚2

    JDOJ 2175: 忠诚2 题目传送门 Description 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家总是让 ...

  4. USACO Slowing down

    洛谷 P2982 [USACO10FEB]慢下来Slowing down 洛谷传送门 JDOJ 2684: USACO 2010 Feb Gold 3.Slowing down JDOJ传送门 Des ...

  5. 网络编程——sockaddr 与 sockaddr_in

    struct sockaddr 这个结构体是linux的网络编程接口中用来表示IP地址的标准结构体,bind.connect等函数中都需要这个结构体,这个结构体是兼容IPV4和IPV6的. 在实际编程 ...

  6. Mysql之配置双主热备+keeepalived.md

    准备 1 1. 双主 master1 192.168.199.49 2 master2 192.168.199.50 3 VIP 192.168.199.52 //虚拟IP 4 2.环境 master ...

  7. web前端图片模糊到清晰的实现过程

    在网页图片显示的时候,会发现许多网站采用了先模糊,然后在慢慢清晰的过程,这样的加载用户体验是比较好的,那么如何实现? 默认加载2张图片,一张缩略图,一张原图,当打开网页的时候默认只显示缩略图,然后我们 ...

  8. 【Gamma】 Phylab 展示博客

    目录 [Gamma] Phylab 展示博客 发布地址 网站:PhyLab GitHub Release: WhatAHardChoice/Phylab Gamma版本 一.团队简介 二.项目目标 2 ...

  9. Spring AOP 代理类,BeanNameAutoProxyCreator cglib

    BeanNameAutoProxyCreator支持拦截接口和类,但不支持已经被jdk代理过的类$Proxy8.使用cglib才能代理,如下 <!-- 通过bean的名字来匹配选择要代理的bea ...

  10. prometheus自定义监控指标——实战

    上一节介绍了pushgateway的作用.优劣以及部署使用,本机通过几个实例来重温一下自定义监控指标是如何使用的. 一.监控容器启动时间(shell) 使用prometheus已经两个月了,但从未找到 ...