首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 事件處理機制深度解析:原理、自訂事件與最佳實務

     編輯:關於C#

事件驅動架構核心

Windows 應用程式基於訊息迴圈:系統偵測硬體輸入 → 封裝為訊息 → 分派至視窗程序 → 觸發對應事件處理器。C# 事件模式封裝此機制,提供型別安全的發布/訂閱介面。

事件實作六步驟

  1. 宣告委派:定義事件處理器簽章 delegate void AlarmEventHandler(object sender, EventArgs e);
  2. 宣告事件:event AlarmEventHandler Alarm; (編譯器產生 add/remove 存取器與私有委派欄位)
  3. 引發方法:慣例命名 OnAlarm(),檢查 if (Alarm != null) Alarm(this, e);
  4. 訂閱事件:dog.Alarm += new Dog.AlarmEventHandler(HostHandleAlarm);
  5. 處理邏輯:實作符合委派簽章的方法
  6. 觸發條件:在適當時機呼叫 OnAlarm()

完整範例:看門狗與主人

// 事件引數自訂
public class ThiefEventArgs : EventArgs {
    public int Count { get; }
    public ThiefEventArgs(int count) => Count = count;
}

// 發送者
public class Dog {
    public delegate void AlarmEventHandler(object sender, ThiefEventArgs e);
    public event AlarmEventHandler Alarm;

    public void OnAlarm(ThiefEventArgs e) {
        Alarm?.Invoke(this, e); // C# 6+ null 條件運算子
    }
}

// 接收者
public class Host {
    public Host(Dog dog) => dog.Alarm += HandleAlarm;

    void HandleAlarm(object sender, ThiefEventArgs e) {
        if (e.Count <= 1) Console.WriteLine("主人: 抓住了小偷!");
        else Console.WriteLine($"主人: 打110報警,我家來了 {e.Count} 個小偷!");
    }
}

// 觸發測試
var dog = new Dog();
var host = new Host(dog);
dog.OnAlarm(new ThiefEventArgs(1)); // 抓住了小偷
dog.OnAlarm(new ThiefEventArgs(3)); // 打110報警

事件模式最佳實務

  • 委派型別命名以 EventHandler 結尾,參數為 (object sender, TEventArgs e)
  • 事件引數繼承 EventArgs,不可變設計
  • 引發方法標記 protected virtual 允許衍生類別覆寫
  • 使用 EventHandler<TEventArgs> 泛型委派減少自訂委派宣告
  • 大量事件考慮 EventHandlerList 儲存節省記憶體
  • 弱事件模式 (WeakEventManager) 防止記憶體洩漏

C# 編譯器背後生成的程式碼

// event AlarmEventHandler Alarm;
// 實際編譯為:
private AlarmEventHandler _alarm;
public event AlarmEventHandler Alarm {
    add { _alarm += value; }
    remove { _alarm -= value; }
}
// 存取器預設為同步鎖定 (lock(this)),可自訂 add/remove 實作無鎖版本

事件流程1
事件流程2
事件流程3

本文對應《叩響 C# 之門》第 16.4 節事件處理機制教學內容

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved