25 Event

Trong C#, sự kiện (event) là một cơ chế cho phép một đối tượng (được gọi là publisher) thông báo cho các đối tượng khác (được gọi là subscribers) khi một hành động cụ thể xảy ra. Điều này thường được sử dụng trong lập trình hướng sự kiện, nơi các thành phần của ứng dụng phản hồi lại các sự kiện như nhấn phím, click chuột hoặc các sự kiện hệ thống khác.

1. Khái niệm về Sự kiện trong C#

Sự kiện là một thành viên của lớp, được khai báo với từ khóa event và một delegate tương ứng. Delegate xác định chữ ký của phương thức sẽ được gọi khi sự kiện được kích hoạt. Các lớp khác có thể đăng ký (subscribe) hoặc hủy đăng ký (unsubscribe) các phương thức xử lý sự kiện với sự kiện này.

Ví dụ:

public delegate void Notify();  // Khai báo delegate

public class ProcessBusinessLogic
{
    public event Notify ProcessCompleted; // Khai báo sự kiện

    public void StartProcess()
    {
        Console.WriteLine("Process Started!");
        // ... thực hiện công việc ...
        OnProcessCompleted();
    }

    protected virtual void OnProcessCompleted()
    {
        // Kiểm tra nếu có phương thức nào đã đăng ký với sự kiện
        ProcessCompleted?.Invoke();
    }
}

Trong ví dụ này, ProcessBusinessLogic có một sự kiện ProcessCompleted được kích hoạt khi quá trình xử lý hoàn tất. Các lớp khác có thể đăng ký phương thức của họ để được thông báo khi sự kiện này xảy ra.

2. Đăng ký và Hủy đăng ký Sự kiện

Các lớp khác có thể đăng ký hoặc hủy đăng ký các phương thức xử lý sự kiện bằng cách sử dụng các toán tử +=-=.

Ví dụ:

public class Program
{
    static void Main(string[] args)
    {
        ProcessBusinessLogic bl = new ProcessBusinessLogic();
        bl.ProcessCompleted += bl_ProcessCompleted; // Đăng ký sự kiện
        bl.StartProcess();
    }

    static void bl_ProcessCompleted()
    {
        Console.WriteLine("Process Completed!");
    }
}

Trong ví dụ này, phương thức bl_ProcessCompleted được đăng ký với sự kiện ProcessCompleted. Khi ProcessCompleted được kích hoạt, bl_ProcessCompleted sẽ được gọi.

3. Sự kiện với Tham số

Để truyền dữ liệu cùng với sự kiện, bạn có thể sử dụng một delegate với tham số hoặc sử dụng EventHandlerEventArgs.

Ví dụ sử dụng EventHandler:

public class ProcessBusinessLogic
{
    public event EventHandler ProcessCompleted; // Sử dụng EventHandler

    public void StartProcess()
    {
        Console.WriteLine("Process Started!");
        // ... thực hiện công việc ...
        OnProcessCompleted(EventArgs.Empty);
    }

    protected virtual void OnProcessCompleted(EventArgs e)
    {
        ProcessCompleted?.Invoke(this, e);
    }
}

Trong ví dụ này, ProcessCompleted sử dụng EventHandler, cho phép truyền thêm thông tin về sự kiện nếu cần.

4. Sự kiện với Tham số Tùy chỉnh

Để truyền dữ liệu tùy chỉnh cùng với sự kiện, bạn có thể tạo một lớp dẫn xuất từ EventArgs.

Ví dụ:

public class ProcessEventArgs : EventArgs
{
    public string Message { get; set; }
}

public class ProcessBusinessLogic
{
    public event EventHandler<ProcessEventArgs> ProcessCompleted;

    public void StartProcess()
    {
        Console.WriteLine("Process Started!");
        // ... thực hiện công việc ...
        OnProcessCompleted(new ProcessEventArgs() { Message = "Process Completed Successfully!" });
    }

    protected virtual void OnProcessCompleted(ProcessEventArgs e)
    {
        ProcessCompleted?.Invoke(this, e);
    }
}

Trong ví dụ này, ProcessEventArgs chứa thông tin bổ sung về sự kiện, cho phép truyền dữ liệu chi tiết hơn đến các subscribers.

5. Quy ước Đặt tên Sự kiện và Delegate

  • Tên sự kiện nên là động từ hoặc cụm động từ, chẳng hạn như ProcessCompleted hoặc DataReceived.
  • Delegate cho sự kiện thường có hai tham số: một đối tượng gửi (object sender) và một đối tượng chứa dữ liệu sự kiện (EventArgs e).

Ví dụ:

public delegate void EventHandler(object sender, EventArgs e);

Bạn cũng có thể sử dụng delegate tổng quát EventHandler<TEventArgs> để truyền dữ liệu sự kiện tùy chỉnh.

Ví dụ:

public event EventHandler<ProcessEventArgs> ProcessCompleted;

6. Sự kiện trong Thư viện .NET

Trong .NET, nhiều sự kiện được xây dựng dựa trên delegate EventHandler. Ví dụ, các sự kiện như Click, KeyDown, Load trong Windows Forms đều sử dụng EventHandler.

Ví dụ:

public event EventHandler Click;

Bạn có thể sử dụng delegate EventHandler để xây dựng các sự kiện tùy chỉnh cho lớp của mình, chỉ cần tạo các lớp dẫn xuất từ EventArgs để thêm các tham số riêng khi gửi sự kiện.

Ví dụ:

public class MyEventArgs : EventArgs
{
    public string Data { get; }

    public MyEventArgs(string data)
    {
        Data = data;
    }
}

public class Publisher
{
    public event EventHandler<MyEventArgs> DataReceived;

    public void RaiseEvent()
    {
        DataReceived?.Invoke(this, new MyEventArgs("Sample Data"));
    }
}

Trong ví dụ này, Publisher có một sự kiện DataReceived sử dụng EventHandler<MyEventArgs>, cho phép truyền dữ liệu tùy chỉnh đến các subscribers.

7. Sự khác biệt giữa Event và Delegate

Tiêu chíDelegateEvent
Định nghĩaLà một kiểu dữ liệu tham chiếu, lưu trữ các phương thức.Là một cơ chế xây dựng trên delegate, hỗ trợ lập trình hướng sự kiện.
Truy cậpCó thể được gọi trực tiếp từ bên ngoài lớp.Chỉ có thể được kích hoạt (invoke) từ bên trong lớp chứa sự kiện.
Mục đíchSử dụng để lưu trữ và gọi các phương thức.Sử dụng để thông báo khi một hành động xảy ra.
Đăng ký/hủy đăng kýHỗ trợ gán, thêm (+=), và loại bỏ (-=) phương thức.Tương tự delegate, nhưng được bảo vệ để ngăn việc gán lại (=).
Tính ứng dụngDùng cho các callback hoặc khi cần quản lý danh sách phương thức.Dùng cho các hệ thống hướng sự kiện, nơi một đối tượng phát tín hiệu và nhiều đối tượng lắng nghe.

8. Khi nào sử dụng Delegate hoặc Event?

Tình huốngSử dụng DelegateSử dụng Event
Callback hoặc phương thức duy nhấtKhi chỉ cần gán hoặc gọi một phương thức cụ thể.Không phù hợp, vì Event cần quản lý nhiều subscriber.
Xử lý sự kiệnDelegate có thể dùng, nhưng Event phù hợp hơn vì bảo mật.Khi một đối tượng phát tín hiệu và nhiều đối tượng khác phản hồi.
Quản lý tập hợp phương thứcKhi cần giữ một danh sách phương thức động.Không phù hợp, vì Event chủ yếu chỉ kích hoạt các phương thức đã đăng ký.
Để lại một bình luận 0

Your email address will not be published. Required fields are marked *