Event ใน C# คืออะไร?
Event ช่วยให้ Class หรือ Object แจ้งเตือน Class/Object อื่นๆ เมื่อมีเหตุการณ์น่าสนใจเกิดขึ้น
- Publisher: Class ที่ Raise Event
- Subscribers: Class ที่ Handle Event
คุณสมบัติสำคัญ
- Event หนึ่งสามารถมี หลาย Subscribers ได้
- Subscriber หนึ่งสามารถ Handle Event จากหลาย Publishers ได้
- Event ที่ไม่มี Subscriber จะไม่ถูก Raise
- Publisher กำหนดเมื่อไหร่ Raise Event, Subscriber กำหนด Action ตอบสนอง
ตัวอย่าง: หลาย Subscribers สำหรับ Event เดียว
class Program
{
static void Main()
{
var video = new MP4() { Title = "Eminem" };
var videoEncoder = new MP4EncoderNew();
var mailService = new MailService();
var messageService = new MessageService();
// Subscribe 2 ตัวด้วย +=
videoEncoder.Mp4Encoded += mailService.OnVideoEncoded;
videoEncoder.Mp4Encoded += messageService.OnVideoEncoded;
videoEncoder.Encode(video);
Console.ReadKey();
}
}
public class MP4 { public string Title { get; set; } }
public class MP4Args : EventArgs
{
public MP4 Mp4 { get; set; }
}
public class MP4EncoderNew
{
public event EventHandler<MP4Args> Mp4Encoded;
public void Encode(MP4 video)
{
Console.WriteLine("Encoding MP4...");
Thread.Sleep(3000);
OnVideoEncoded(video);
}
protected virtual void OnVideoEncoded(MP4 video)
{
Mp4Encoded?.Invoke(this, new MP4Args() { Mp4 = video });
}
}
// Subscriber 1
public class MailService
{
public void OnVideoEncoded(object sender, MP4Args e)
{
Console.WriteLine($"Mail Service: Sending email for {e.Mp4.Title}");
}
}
// Subscriber 2
public class MessageService
{
public void OnVideoEncoded(object sender, MP4Args e)
{
Console.WriteLine($"Message Service: Sending message for {e.Mp4.Title}");
}
}
Output
Encoding MP4... Mail Service: Sending email for Eminem Message Service: Sending message for Eminem
Best Practice
- ใช้
?.Invoke()แทนการเช็ค null แบบเก่า - ใช้
EventHandler<TEventArgs>แทน Delegate แบบ Custom - Unsubscribe ด้วย
-=เมื่อไม่ต้องการแล้ว เพื่อป้องกัน Memory Leak