如何訂閱和取消訂閱 (C# 程式設計指南)

如果您想要撰寫在引發事件時所呼叫的自訂程式碼,您可以訂閱由其他類別發行的事件。 例如,您可以訂閱某個按鈕的 click 事件,讓應用程式在使用者按下該按鈕時執行某項動作。

使用 Visual Studio IDE 訂閱事件

  1. 如果看不到 [屬性] 視窗,請在 [設計] 檢視中,以滑鼠右鍵按一下您要建立事件處理常式的表單或控制項,然後選取 [屬性]

  2. 在 [屬性] 視窗頂端,按一下事件圖示。

  3. 按兩下您要建立的事件,例如 Load 事件。

    Visual C# 會建立空的事件處理常式方法,並將其新增至您的程式碼。 您也可以在 [程式碼] 檢視中手動新增程式碼。 例如,下列程式碼行會宣告一個事件處理常式方法,該方法將會在 Form 類別引發 Load 事件時呼叫。

    private void Form1_Load(object sender, System.EventArgs e)
    {
        // Add your form load event handling code here.
    }
    

    訂閱事件所需的程式碼行也會在專案之 Form1.Designer.cs 檔案的 InitializeComponent 方法中自動產生。 看起來像這樣:

    this.Load += new System.EventHandler(this.Form1_Load);  
    

以程式設計方式訂閱事件

  1. 定義事件處理常式方法,其簽章與事件的委派簽章相符。 例如,如果事件是以 EventHandler 委派類型為基礎,則下列程式碼代表方法 Stub:

    void HandleCustomEvent(object sender, CustomEventArgs a)  
    {  
       // Do something useful here.  
    }  
    
  2. 請使用加法指派運算子 (+=) 來將事件處理常式附加到事件。 在下列範例中,假設名為 publisher 的物件具有名為 RaiseCustomEvent 的事件。 請注意,subscriber 類別需要參考 publisher 類別,才能訂閱其事件。

    publisher.RaiseCustomEvent += HandleCustomEvent;  
    

    您也可以使用 Lambda 運算式 來指定事件處理常式:

    public Form1()  
    {  
        InitializeComponent();  
        this.Click += (s,e) =>
            {
                MessageBox.Show(((MouseEventArgs)e).Location.ToString());
            };
    }  
    

使用匿名函式訂閱事件

如果您稍後不需要取消訂閱事件,您可以使用加法指派運算子 (+=) 附加匿名函式作為事件處理常式。 在下列範例中,假設名為 publisher 的物件具有名為 RaiseCustomEvent 的事件,而且也已定義 CustomEventArgs 類別來包含特定類型的特製化事件資訊。 請注意,subscriber 類別需要參考 publisher,才能訂閱其事件。

publisher.RaiseCustomEvent += (object o, CustomEventArgs e) =>
{  
  string s = o.ToString() + " " + e.ToString();  
  Console.WriteLine(s);  
};  

如果您使用匿名函式訂閱事件,則無法輕易取消訂閱事件。 若要取消訂閱此案例,請回到您訂閱事件的程式碼、將匿名函式儲存在委派變數中,然後將委派新增至事件。 如果您需要在程式碼稍後的某個時間點取消訂閱事件,建議您不要使用匿名函式來訂閱事件。 如需匿名函式的詳細資訊,請參閱 Lambda 運算式

取消訂閱

若要防止在引發事件時叫用事件處理常式,請取消訂閱事件。 為了避免資源流失,請先取消訂閱事件,再處置訂閱者物件。 在取消訂閱事件之前,發行物件的事件之下的多點傳送委派都會參考封裝訂閱者事件處理常式的委派。 只要發行物件還有該參考,記憶體回收就不會刪除訂閱者物件。

取消訂閱事件

  • 使用減法指派運算子 (-=) 取消訂閱事件:

    publisher.RaiseCustomEvent -= HandleCustomEvent;  
    

    在所有訂閱者都已取消訂閱事件之後,publisher 類別中的事件執行個體會設定為 null

另請參閱