C#和java比較: java中使用的是接口。
C#使用委託機制,能夠用時 + 運算符進行註冊,直接多播。 而java中是通常是使用一個集合來保存觀察者。java
發佈者(Publisher)= 被觀察者 (Observable) = 事件源(java中的EventObject,C#中的sender)
訂閱者(Subscriber)=觀察者(Observer) = 接收者(java中繼承EventLister,接口, 或Observer接口, C#因爲委託機制,不須要繼承接口,直接按EventHandler實現回調方法)異步
在發生其餘類或對象關注的事情時,類或對象可經過事件通知它們。發送(或引起)事件的類稱爲「發行者」,接收(或處理)事件的類稱爲「訂戶」。
在典型的 C# Windows 窗體或 Web 應用程序中,可訂閱由控件(如按鈕和列表框)引起的事件。可以使用 Visual C# 集成開發環境 (IDE) 來瀏覽控件發佈的事件,選擇要處理的事件。IDE 會自動添加空事件處理程序方法和訂閱事件的代碼。ide
EventHandler爲C#中的預約義委託,專用於表示不生成數據的事件的事件的處理程序方法。
public delegate void EventHandler(
Object sender,
EventArgs e
)
事件具備如下特色:
1.發行者肯定什麼時候引起事件,訂戶肯定執行何種操做來響應該事件。
2.一個事件能夠有多個訂戶。一個訂戶可處理來自多個發行者的多個事件。
3.沒有訂戶的事件永遠不會被調用。
4.事件一般用於通知用戶操做(如:圖形用戶界面中的按鈕單擊或菜單選擇操做)。
5.若是一個事件有多個訂戶,當引起該事件時,會同步調用多個事件處理程序。要異步調用事件,請參見使用異步方式調用同步方法。
6.能夠利用事件同步線程。
7.在 .NET Framework 類庫中,事件是基於 EventHandler 委託和 EventArgs 基類的。函數
下面的示例演示了上述步驟,它將自定義 EventArgs 類和 EventHandler<T> 用做事件類型。this
namespace ConsoleApplication2 { using System; using System.Collections.Generic; // 自定義一個事件類來保存事件信息 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; // 註冊事件,使用C#2.0語法 //註冊這個動做,應該有訂閱者主動進行,而且能夠再後期取消註冊 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(); // Keep the console window open Console.WriteLine("Press Enter to close this window."); Console.ReadLine(); } } }