前言:
观测者模型的基本理念,就是,我有一个公共的事件,定义好他的事件的触发、数据接口。然后,通过增加订阅者(实例)来订阅这个事件的,或者说观察这个事件。如果事件发生,订阅了事件或订阅了观察的类就执行这个时间的方法(触发的执行)。
这种方式的好处,就是解耦了生产者(事件发生)和消费者(事件处理)的绑定关系,注册观察了再执行,否则不执行。
1 观察者(发布-订阅)模式的构建:
1.1 EventHandler(系统定义的事件委托Handler,也就是处理事件的方法)
C# Formworks 定义的事件定义在 System.EventHandler
中的委托,包括事件发送者,和发送的事件数据对象两个参数。
2 定义数据事件提供者类
定义了一个名为 DataEventProvider
的公共静态类
2.1.1 定义事件 DataChanged和事件的句柄(接口)
:
数据事件提供者,首先要有一个事件,这里就是DataChanged。
public static class DataEventProvider
{
public static event EventHandler<DataChangedEventArgs> DataChanged;
public static void OnDataChanged(IFrameOut newFrame)
{
DataChanged?.Invoke(null, new DataChangedEventArgs(newFrame));
}
}
有了事件DataChanged,同时还提供一个,事件的接口,也就是你要通知订阅的人发生了声明,然后,给粗发生的事情的证据(数据)
也就是,出事了,然后,有这么一堆数据(来说明,和准备处理)、
EventArgs 就是来说明什么事件的,但,他默认的定义是空的,就等着你构建事件的时候,自己去定义需要哪些证据。
在,我们的案例里面,我们就把EventArgs,给泛型(也就是说明白了),那么通过EventHandler<DataChangedEventArgs>,把接口泛型到DataChangedEventArgs的定义里面,如下:
public class DataChangedEventArgs : EventArgs
{
public IFrameOut NewFrame { get; } //拿到数据
public DataChangedEventArgs(IFrameOut newFrame)
{
NewFrame = newFrame; // 给到事件订阅者
}
}
在DataChangedEventArgs里面,我们清楚的定义了一个IFrame的图像的处理数据,拿到数据,同时把数据传递给事件订阅者,作为事件要处理的接口。
【案】, public static event EventHandler<DataChangedEventArgs> DataChanged;
DataChanged
是一个公共的静态事件。
他的定义详细如下:
1 public static:类级别的公共静态变量2 event类型:是一种特殊的成员,允许对象订阅和响应由其他对象发出的信号或消息。
3 为
EventHandler<DataChangedEventArgs>
。
EventHandler 第一节已经说了,<DataChangedEventArgs>是EventHandler的泛型版本,表示事件处理方法EventHandler将接受<DataChangedEventArgs>泛型定义的参数,这里我们的<DataChangedEventArgs>是我们自己定义的一个类。派生于EventArgs,因此他也依旧包括EventHandler已经有的相关的数据。
总之,我们的定义了一个 公共的静态事件,类型为
EventHandler<DataChangedEventArgs>
。这意味着它可以与任何符合EventHandler
委托定义的方法关联,并且这些方法将接收一个DataChangedEventArgs
类型的参数。
2.1.2 定义事件的方法 OnDataChanged:
【案】, public static void OnDataChanged(IFrameOut newFrame)
OnDataChanged 是一个静态方法, ,这里接受了一个IFrameOut的参数。
DataChanged?.Invoke(null, new DataChangedEventArgs(newFrame));
这里,DataChanged为之前定义的事件名,
1 条件运算符?C# 6引入的null条件运算符。它允许你在尝试调用对象的成员之前检查对象(这里为事件源对象,或者观察者)是否为null。如果对象不是null,就执行成员访问;如果是null,则不执行任何操作,并且表达式的结果为null。
这样做的另外一个好处是,线程安全。
2
Invoke
方法
Invoke
是EventHandler
委托的实例方法,用于触发事件。它接受两个参数:第一个是事件源(通常是一个对象实例),第二个是包含事件数据的EventArgs
类型的实例。我们之前定义的时候,知道DataChangedEventArgs泛型,继承了之前EventHandler
有的两个基本数据。- 在这个例子中,
Invoke
被用来触发DataChanged
事件,通知所有订阅者发生了数据变化。
3 观察者(发布-订阅)模式的使用:
3.1定义一个观测者事件:
例如,我们在Form1,订阅了这个事件
private void OnDataChanged(object sender, DataChangedEventArgs e)
{
// 拿到事件的参数数据
IFrameOut frameOut = e.NewFrame;
// 后续进行处理
}
3.2 注册一个观测者事件
事件的注册,或者观测者,通过将一个事件处理方法,加到事件定义里面来注册
DataEventProvider.DataChanged += OnDataChanged;
3.3 触发一个事件发生:
DataEventProvider.OnDataChanged(frameOut);
3.4 取消观察:
DataEventProvider.DataChanged -= OnDataChanged;