.NET中的事件模式是如何工作的?


事件是一種使用委託的簡化模式。在C#中,所有委託都具有多播能力,即委託的例項不僅可以表示單個方法,還可以表示方法列表。例如:

示例

delegate int Transformer(int x);
static void Main(){
   Transformer perform = x =>{
      int result = x * x;
      Console.WriteLine(result);
      return result;
   };
   perform += x =>{
      int result = x * x * x;
      Console.WriteLine(result);
      return result;
   };
   perform(2); // prints 4 and 8
}

呼叫Perform()會呼叫新增到委託中的所有方法。方法按照新增的順序呼叫。

這允許你實現釋出-訂閱模式,也稱為事件模式。釋出者包含一個委託欄位。它決定何時透過呼叫委託來發布。訂閱者將自己的方法新增到釋出者的委託中,因此每當釋出者決定透過呼叫委託來發布時,它們都會收到通知。訂閱者不知道也不干涉其他訂閱者。

C#事件是一種語言特性,它以型別安全的方式規範了上述模式,從而避免了委託的常見錯誤。事件公開實現事件模式所需的委託功能的子集。下面的示例對此進行了說明。

首先,定義事件發生時要傳送的資料結構。

public class ThresholdReachedEventArgs : EventArgs{
   public int Threshold { get; set; }
   public DateTime TimeReached { get; set; }
}

然後,定義釋出者,即想要引發事件的類。

public class Counter{
   // 1. Define an event
   public event EventHandler<ThresholdReachedEventArgs> ThresholdReached;
   // 2. Do something that raises the event, and pass the EventArgs custom data
   public void DoSomething(){
      ThresholdReachedEventArgs e = new ThresholdReachedEventArgs{
         Threshold = 10,
         TimeReached = DateTime.Now
      };
      // 3. Raise the actual event
      ThresholdReached?.Invoke(this, e);
   }
}

最後,建立一個或多個訂閱者。想要監聽釋出者引發的事件的類。

class Program{
   static void Main(string[] args){
      // 1. Create an instance of the publisher, which you want to listen to
      Counter counter = new Counter();
      // 2. Attach an event handler on the publisher
      counter.ThresholdReached += OnThresholdReached;
      // 3. Do something that will raise the event. Now you are ready to listen to the event.
      counter.DoSomething();
   }
   // 4. Handle the event which is raised by publisher
   static void OnThresholdReached(object sender, ThresholdReachedEventArgs e){
      Console.WriteLine($"Reached Threshold {e.Threshold} at {e.TimeReached.ToString()}");
   }
}

示例

線上演示

using System;
class Program{
   static void Main(string[] args){
      // 1. Create an instance of the publisher, which you want to listen to
      Counter counter = new Counter();

      // 2. Attach an event handler on the publisher
      counter.ThresholdReached += OnThresholdReached;

      // 3. Do something that will raise the event. Now you are ready to listen to the       event.
      counter.DoSomething();
   }

   // 4. Handle the event which is raised by publisher
   static void OnThresholdReached(object sender, ThresholdReachedEventArgs e){
      Console.WriteLine($"Reached Threshold {e.Threshold} at {e.TimeReached.ToString()}");
   }
}
public class ThresholdReachedEventArgs : EventArgs{
   public int Threshold { get; set; }
   public DateTime TimeReached { get; set; }
}
public class Counter{
   // 1. Define an event
   public event EventHandler<ThresholdReachedEventArgs> ThresholdReached;
   // 2. Do something that raises the event, and pass the EventArgs custom data
   public void DoSomething(){
      ThresholdReachedEventArgs e = new ThresholdReachedEventArgs{
         Threshold = 10,
         TimeReached = DateTime.Now
      };
      // 3. Raise the actual event
      ThresholdReached?.Invoke(this, e);
   }
}

輸出

Reached Threshold 10 at 5/15/2021 12:49:10 PM

更新於:2021年5月19日

475 次瀏覽

啟動你的職業生涯

透過完成課程獲得認證

開始學習
廣告