在所有關於C#事件機制的介紹中,我更傾向於發布者/訂閱者(Publisher/Subscriber)這種描述。理解事件機制並不是一件容易的事情,它所涉及的思想值得我們好好去研究。
本文資源來自《C#與.NET技術平台實戰演練》——中國青年出版社
談到事件,我們涉及到兩個角色:事件發布者(Publisher)和事件訂閱者(Scriber),也可以說是事件發送者(Sender)和事件接收者(Receiver)的關系。舉個例子來說,市面上目前有許多雜志,雜志的種類也很多。而我只對其中的某些感興趣,那么我就可以向雜志發行商提出訂閱。之后,每當雜志發行時,我就會收到我在雜志發行商那兒訂閱的雜志。在這個關系中,雜志發行商就相當於事件發行者,而我就是事件訂閱者。每當雜志發行時,就觸發了一個發行事件。
用面向對象的語言解釋,這兩者的意義如下:
事件發行者(Publisher)
它是一個對象,且會維護自身的狀態信息。每當狀態信息發生變動時,便觸發一個事件,並通知所有的事件訂閱者。對於雜志發行商來說,每本雜志都有自己的信息在里面,當雜志發行時,我要通知訂閱該雜志的人:雜志已經發行啦,請注意查收!
事件接收者(Receiver)
這個對象要注冊它感興趣的對象,也就是訂閱它自己喜歡的雜志啦。另外,這個對象通常要提供一個事件處理方法,在事件發行者觸發一個事件后,會自動執行這個方法。對於上面所舉的例子來說,也就是我收到雜志后要做什么事情,比如,你可以滿世界地大喊:我收到雜志啦!也可以將雜志收藏起來慢慢欣賞,具體怎么實現完全取決你自己的喜好。
以下是.NET事件處理機制的模型:
說明:可以注冊多個事件處理程序
下面給出一個例子:
FileWatch.cs內容:
using System;
using System.Collections.Generic;
using System.Linq;
namespace WindowsFormsEventTest
{
// 1、委托 (指向函數的指針 類型)
public delegate void FileChangedEventHandler(object sender, MyEventArgs e);
class FileWatch
{
//2、事件 (指向函數的指針變量 ——FileChangedEvent)
public event FileChangedEventHandler FileChangedEvent;
//3、觸發事件的方法
public virtual void OnFileChange(MyEventArgs e)
{
if (FileChangedEvent != null)
{
FileChangedEvent(this, e);
}
}
}
}
Form1.cs文件內容如下:
using System;
using System.Windows.Forms;
namespace WindowsFormsEventTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
FileWatch EventSource = new FileWatch();//定義對象
EventSource.FileChangedEvent += new FileChangedEventHandler(FileChangeHandle);//注冊事件(為指針賦值) +=
EventSource.FileChangedEvent += new FileChangedEventHandler(FileChangeHandle2);// 注冊事件(為指針賦值)
EventSource.OnFileChange(e);
for (int i= 0; i < 500000000; ++i)
{
}
EventSource.OnFileChange(e);
for (int i = 0; i < 500000000; ++i)
{
}
EventSource.OnFileChange(e);
}
public void FileChangeHandle(object obj,MyEventArgs e)
{
listBox1.Items.Add(DateTime.Now.ToString() + " : 文件發生改變." +"Message:"+e.Info);
}
public void FileChangeHandle2(object obj, MyEventArgs e)
{
listBox2.Items.Add(DateTime.Now.ToString() + " : 文件發生改變." + "Message:" + e.Info);
}
}
}