Delegate và Event trong Csharp

Khái niệm delegate được hiểu như là một con trỏ hàm (method). Thực tế là một method nó cũng có 1 vùng nhớ xác định trên Ram và khi biết được địa chỉ của vùng nhớ này thì mình có thể gọi method thực hiện, bình thường mình gọi method thông qua đối tượng (instance) hoặc tên class (nếu là method static) và tên method. Như vậy một delegate được hiểu nôm na là một kiểu dùng để lưu trữ 1 hay nhiều địa chỉ method mà những method này phải cùng prototype (gồm kiểu trả về và danh sách các tham số). Khi ta có một biến delegate đang nắm giữ danh sách các method (có cùng prototype với nó) thì chỉ cần khởi động biến này tất cả các danh sách method đó sẽ được thực hiện lần lượt mà ta không cần quan tâm đến tên method đó nữa.

Delegate rất có ý nghĩa khi kết hợp với event, như bác sangcn đã đề cập thì event là một thể hiện đặc biệt của delegate. Theo khái niệm thì event là một thông điệp được gửi tới những đối tượng đã đăng ký trước đó để thực hiện hành động nào đó kèm theo khi thông điệp đó được gửi tới (nghĩa là sự kiện đó xảy ra). Ví dụ, khi chúng ta click chuột vào 1 nút (button) nào đó trên một form (cửa sổ ứng dụng), nghĩa là lúc này đối tượng nút sẽ truyền một thông điệp (phát ra sự kiện nhấn chuột) cho đối tượng form để gọi tới method mà form này đã đăng ký nhận thông điệp khi sự kiện nhấn chuột xảy ra.

Một ứng dụng cụ thể để hiểu mục đích sử dụng delegate event đó là chúng ta viết một class clock (đồng hồ), và một yêu cầu rằng khi người ta sử dụng đối tượng clock này thì muốn nhận một thông điệp (sự kiện) EndTime (hết giờ) để thực hiện một hành động gì đó kèm theo sự kiện này. Ví dụ ta viết một chương trình game đoán chữ và có giới hạn thời gian cho người chơi là 10 giây, hết thời gian này thì chương trình sẽ thông báo "Time over" chẳng hạn. Như vậy, ta sẽ cần ít nhất 2 class là Game và Clock. Chúng ta hãy xem mã nguồn để thể hiện ví dụ này.

public class Clock
{
    private int _second;
    // Định nghĩa một delegate để trỏ vào những method có kiểu không đối số, không kiểu trả về
    public delegate void TimeOver();
    // Khai báo 1 event thuộc kiểu delegate trên
    public event TimeOver EndTime;
    public Clock(int second)
    {
        _second = second;
    }
    public int Second
    {
        get { return _second; }
        set { _second = value; }
    }
    /// 
    /// Method đếm lùi thời gian cho đến khi _second = 0 thì kết thúc và báo lên sự kiện EndTime
    /// 
    public void Timedown()
    {
        do
        {
            _second--;
            Thread.Sleep(1000);
        }
        while (_second > 0);
        // trước khi gọi event hoặc delegate thì cần kiểm tra biến có null không (nghĩa là có chứa địa chỉ
        // của method nào không) nếu khác null (có chứa 1 ít nhât 1 method) thì mới gọi.
        if (EndTime != null)
            EndTime(); // gọi thực hiện các method đã đăng ký sự kiện.
    }
}
class Game
{
    /// 
    /// Method dùng để thực hiện hành động kèm theo khi sự kiện EndTime (delegate TimeOver) xảy ra
    /// 
    public void GameOver()
    {
        Console.WriteLine("Game over");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Clock c = new Clock(10);
        Game g = new Game();
        // Đăng ký method thực hiện hành động kèm theo khi có sự kiện EndTime xảy ra
        c.EndTime += new Clock.TimeOver(g.GameOver);
        ThreadStart ts = new ThreadStart(c.Timedown);
        Thread ChildThread = new Thread(ts);
        ChildThread.Start();
        Console.WriteLine("Waiting about 10 second...");
    }
}

Chủ đề này là một chủ đề lớn và rất hay vì thế sẽ có video để chúng ta tìm hiểu sâu hơn nữa. Hy vọng bạn cũng phần nào nắm được. Tôi gửi link download mã nguồn cho ví dụ trên để bạn tiện tham khảo.

DemoEvent.rar (23,46 kb)

Nguồn: http://www.hoctinhoctructuyen.com/Questions?page=3&TypeSearch=-1