Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

วิธี Subscribe Event ใน C# และสามารถมีหลาย Subscribers ได้หรือไม่

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