C# 事件機制

隨夢而飛發表於2015-04-13

在所有關於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);

}

 

}

}

相關文章