下面的程序演示了如何將遵循標準 .NET 模式的事件添加到類和結構中,The following procedure demonstrates how to add events that follow the standard .NET pattern to your classes and structs. .NET 類別庫中的所有事件均基于 EventHandler 委托,定義如下:All events in the .NET class library are based on the EventHandler delegate, which is defined as follows:
C#publicdelegate void EventHandler(object sender, EventArgs e);
備注
.NET Framework 2.0 引入了泛型版本的委托 EventHandler<TEventArgs>,.NET Framework 2.0 introduces a generic version of this delegate, EventHandler<TEventArgs>. 下例演示了如何使用這兩個版本,The following examples show how to use both versions.
盡管定義的類中的事件可基于任何有效委托型別,甚至是回傳值的委托,但一般還是建議使用 EventHandler 使事件基于 .NET 模式,如下例中所示,Although events in classes that you define can be based on any valid delegate type, even delegates that return a value, it is generally recommended that you base your events on the .NET pattern by using EventHandler, as shown in the following example.
名稱 EventHandler 可能導致一些混淆,因為它不會實際處理事件,The name EventHandler can lead to a bit of confusion as it doesn't actually handle the event. EventHandler 和泛型 EventHandler<TEventArgs> 均為委托型別,The EventHandler, and generic EventHandler<TEventArgs> are delegate types. 其簽名與委托定義匹配的方法或 Lambda 運算式是事件處理程式,并將在引發事件時呼叫,A method or lambda expression whose signature matches the delegate definition is the event handler and will be invoked when the event is raised.
發布基于 EventHandler 模式的事件Publish events based on the EventHandler pattern
-
(如果無需隨事件一起發送自定義資料,請跳過此步驟轉到步驟 3a,)將自定義資料的類宣告為對發布服務器和訂閱者類均可見的范圍,(Skip this step and go to Step 3a if you do not have to send custom data with your event.) Declare the class for your custom data at a scope that is visible to both your publisher and subscriber classes. 然后添加所需成員以保留自定義事件資料,Then add the required members to hold your custom event data. 在此示例中,將回傳一個簡單的字串,In this example, a simple string is returned.
C#public class CustomEventArgs : EventArgs { public CustomEventArgs(string message) { Message = message; } public string Message { get; set; } } -
(如果使用的是泛型版本 EventHandler<TEventArgs>,請跳過此步驟,)宣告發布類中的委托,(Skip this step if you are using the generic version of EventHandler<TEventArgs>.) Declare a delegate in your publishing class. 為其指定以
C#EventHandler結尾的名稱,Give it a name that ends withEventHandler. 第二個引數指定自定義EventArgs型別,The second parameter specifies your customEventArgstype.public delegate void CustomEventHandler(object sender, CustomEventArgs args); -
使用下列步驟之一來聲明發布類中的事件,Declare the event in your publishing class by using one of the following steps.
-
如果沒有任何自定義 EventArgs 類,事件型別將為非泛型 EventHandler 委托,If you have no custom EventArgs class, your Event type will be the non-generic EventHandler delegate. 你無需宣告該委托,因為它已在創建 C# 專案時包括的 System 命名空間中宣告,You do not have to declare the delegate because it is already declared in the System namespace that is included when you create your C# project. 將以下代碼添加到發布服務器類,Add the following code to your publisher class.
C#public event EventHandler RaiseCustomEvent; -
如果使用非泛型版本 EventHandler 并且具有派生自 EventArgs 的自定義類,請宣告發布類中的事件,并將步驟 2 中的委托用作型別,If you are using the non-generic version of EventHandler and you have a custom class derived from EventArgs, declare your event inside your publishing class and use your delegate from step 2 as the type.
C#public event CustomEventHandler RaiseCustomEvent; -
如果使用泛型版本,則無需自定義委托,If you are using the generic version, you do not need a custom delegate. 而是在發布類中,將事件型別指定為
C#EventHandler<CustomEventArgs>,替換尖括號中自定義類的名稱,Instead, in your publishing class, you specify your event type asEventHandler<CustomEventArgs>, substituting the name of your own class between the angle brackets.public event EventHandler<CustomEventArgs> RaiseCustomEvent;
-
示例Example
下例通過使用自定義 EventArgs 類和 EventHandler<TEventArgs> 作為事件型別來演示之前的步驟,The following example demonstrates the previous steps by using a custom EventArgs class and EventHandler<TEventArgs> as the event type.
C#using System;
namespace DotNetEvents
{
// Define a class to hold custom event info
public class CustomEventArgs : EventArgs
{
public CustomEventArgs(string message)
{
Message = message;
}
public string Message { get; set; }
}
// Class that publishes an event
class Publisher
{
// Declare the event using EventHandler<T>
public event EventHandler<CustomEventArgs> RaiseCustomEvent;
public void DoSomething()
{
// Write some code that does something useful here
// then raise the event. You can also raise an event
// before you execute a block of code.
OnRaiseCustomEvent(new CustomEventArgs("Event triggered"));
}
// Wrap event invocations inside a protected virtual method
// to allow derived classes to override the event invocation behavior
protected virtual void OnRaiseCustomEvent(CustomEventArgs e)
{
// Make a temporary copy of the event to avoid possibility of
// a race condition if the last subscriber unsubscribes
// immediately after the null check and before the event is raised.
EventHandler<CustomEventArgs> raiseEvent = RaiseCustomEvent;
// Event will be null if there are no subscribers
if (raiseEvent != null)
{
// Format the string to send inside the CustomEventArgs parameter
e.Message += $" at {DateTime.Now}";
// Call to raise the event.
raiseEvent(this, e);
}
}
}
//Class that subscribes to an event
class Subscriber
{
private readonly string _id;
public Subscriber(string id, Publisher pub)
{
_id = id;
// Subscribe to the event
pub.RaiseCustomEvent += HandleCustomEvent;
}
// Define what actions to take when the event is raised.
void HandleCustomEvent(object sender, CustomEventArgs e)
{
Console.WriteLine($"{_id} received this message: {e.Message}");
}
}
class Program
{
static void Main()
{
var pub = new Publisher();
var sub1 = new Subscriber("sub1", pub);
var sub2 = new Subscriber("sub2", pub);
// Call the method that raises the event.
pub.DoSomething();
// Keep the console window open
Console.WriteLine("Press any key to continue...");
Console.ReadLine();
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/242642.html
標籤:.NET技术
下一篇:RabbitMQ跟CAP簡單入門
