20180503
事件
事件是什么
当某些感兴趣的事发生时,事件允许某个类或对象通知其他类或对象。发送事件的类称为publisher,接收或处理事件的类称为subscribers;
事件的特点
- publisher决定事件什么时候出发,subscribers决定事件发生后要采取的行为;
- 同一事件可以有多个subscribers;同一个subscriber可以处理来自不同publishers的事件;
- 没有subscribers的事件不会被触发;
事件的作用(使用场景)
事件是在对象之间(进程间inter-process)传递消息的机制;
减少应用程序内部的耦合;
- 扩展应用程序;
委托
- 在Publisher和Subscribers之间的协议;
- 确定位于Subscribers内部事件处理方法的签名;
事件的使用
Publisher中:
- 定义委托
- 定义基于委托的事件
- 引发事件(raise an event)
Subscribers中:
- 实现虚方法;(或者其他与委托对应的方法)
图示
sequenceDiagram
主程序->>热水器: 声明Publisher对象
主程序->>警报器: 声明Subscriber对象
主程序->>显示器: 声明Subscriber对象
热水器->>警报器: 注册事件
热水器->>显示器: 注册事件
主程序->>热水器: 引发事件(raise the event)
其中,警报器,显示器需要实现触发事件后执行的方法。
例子
//Subscribers
public class MessageService
{
public void OnVideoEncoded(object source,EventArgs e)
{
Console.WriteLine("MessageService:Sending a text message...");
}
}
//publisher
public class VideoEncoder
{
//1.定义委托
//2.定义基于委托的事件
//3.引发事件
public delegate void VideoEncodedEventHandler(object source,EventArgs args);
public event VideoEncodedEventHandler VideoEncoded;;
//可以不用每次都声明委托,以上两条语句可以用下面这句代替:
//public event EventHandler<VideoEventArgs> VideoEncoded;
//不需要传递多余参数
//public event EventHandler VideoEncoded;
public void Encode(Video video)
{
Console.WriteLine("Encoding Video...");
Thread.Sleep(3000);
OnVideoEncoded();
}
protected virtual void OnVideoEncoded()
{
if(VideoEncoded!=null)
{
VideoEncoded(this,EventArgs.Empty);
}
}
}
//Main
static void Main(string[] args)
{
var video = new Video(){Title = "Video 1"};
var videoEncoder = new VideoEncoder();//publisher
var messageService = new MessageService();//subscriber
videoEncoder.VideoEncoded += messageService.OnvideoEncoded;
//触发事件
videoEncoder.Encode(video);
}
//Video.cs
public class Video()
{
get;
set;
}