前言
发布者(Publisher)= 被观察者(Observable) = 事件源(C#中的sender)
订阅者(Subscriber)=观察者(Observer)= 接收者(C#委托机制,直接按EventHandler实现回调方法)—>来源于DotNet工控上位机编程 公众号
一、EventHandler 是什么?
EventHandler 为 C# 中的预定义委托,专用于表示不生成数据的事件的事件的处理程序方法。
public delegate void EventHandler(Object sender, EventArgs e)–>来源于DotNet工控上位机编程 公众号
二、应用场景
1.使用方面
1.当一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两者封装在独立的对象中以使它们可以各自独立地改变和复用的情况下。
2.当对一个对象的改变需要同时改变其他对象,而又不知道具体有多少对象有待改变的情况下。
3.当一个对象必须通知其他对象,而又不能假定其他对象是谁的情况下。
2.使用的优点
1.各个观察者或不干扰,只需要实现本身(观察者)的功能。
2.可随时进行绑定和解绑是否需要接受发布的通知。
三.使用说明Demo
1.Subject类
/// <summary>
/// Subject只是用于发布作用的类,类中包含将订阅的类加入集合函数AttachObserver,包含解除订阅的函数RemoveObserver,最主要是包含了发布通知函数NotifyAllObserver
/// </summary>
public class Subject
{
//将所有观察者放入list集合
private List<Observer> observers = new List<Observer>();
public void NotifyAllObserver()
{
foreach (Observer item in observers)
{
//调用观察者自身的更新函数即可
item.Update();
}
}
/// <summary>
/// 加入集合
/// </summary>
/// <param name="observer"></param>
public void AttachObserver(Observer observer)
{
observers.Add(observer);
}
/// <summary>
/// 从观察者列表中去除
/// </summary>
/// <param name="observer"></param>
public void RemoveObserver(Observer observer)
{
observers.Remove(observer);
}
}
2.Observer观察者抽象类
/// <summary>
/// 观察者抽象类
/// </summary>
public abstract class Observer
{
protected Subject subject;
public abstract void Update();//抽象类中的函数只是写个名称,具体实现需要继承的子类中进行
}
3.具体观察者,需要继承Observer基类,并且实现Update更新
public class Observer_A : Observer
{
public Observer_A(Subject subject)
{
this.subject = subject;
this.subject.AttachObserver(this);//绑定Observer_A订阅者
}
//实现抽象类的方法,不开放出去
public override void Update()
{
//这里编写Observer_A类中具体要实现的内容
}
}
public class Observer_B : Observer
{
public Observer_B(Subject subject)
{
this.subject = subject;
this.subject.AttachObserver(this);//绑定Observer_B订阅者
}
public override void Update()
{
//这里编写Observer_A类中具体要实现的内容
}
}
四.调用
Subject obj_subject = new Subject();
new Observer_A(obj_subject);
new Observer_B(obj_subject);
obj_subject.NotifyAllObserver();
使用事件也是同样道理。以下代码来源于DotNet工控上位机编程 公众号,作者DotNet天天编程
// 自定义一个事件类来保存事件信息
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;//注册这个动作,应该有订阅者主动进行,并且可以再后期取消注册
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();
Console.WriteLine("Press Enter to close this window.");
Console.ReadLine();
}
}