C# WinForms Thread Safety with Invoke

Tran Van Ngoc|

TL;DR

Trong lập trình Windows Forms (C#), mọi tương tác với UI controls (vẽ giao diện, nhận tương tác) bắt buộc phải do luồng chính Main UI Thread xử lý. Khi các tác vụ nền Background Threads cần đụng chạm UI, chúng phải thông qua cơ chế Invoke() để gửi yêu cầu nhờ luồng chính xử lý, tránh lỗi xung đột luồng Cross-thread operation.

Analogy

Hãy tưởng tượng luồng của ứng dụng giống như một Nhà hàng:

  • Main UI Thread (Bồi bàn): Chỉ phục vụ ngoài sảnh (vẽ giao diện, nhận click chuột).
  • Background Thread (Đầu bếp): Chỉ làm việc nặng trong bếp (gọi DB, tải file).
  • Đầu bếp không được phép tự mang đồ ra sảnh đặt vào bàn khách (Background thread không được can thiệp trực tiếp vào UI). Thay vào đó, Đầu bếp phải đặt món lên quầy, bấm chuông (Invoke) nhờ Bồi bàn đem ra. Việc va chạm ngoài sảnh do Đầu bếp chạy trực tiếp ra sẽ gây đổ vỡ (Lỗi Cross-thread operation).

Workflow & Code Example

1. Kịch bản lỗi

// Chạy trên Background Thread
private void BackgroundTask() {
    // LỖI: Luồng nền đang can thiệp trực tiếp vào UI control
    txtReason.Focus();
}

2. Kịch bản sửa lỗi với Invoke

// Chạy trên Background Thread
private void BackgroundTask() {
    // Sử dụng Invoke để nhờ Main Thread xử lý hộ
    this.Invoke((MethodInvoker)delegate {
        txtReason.Focus();
    });
}