Vòng lặp thông báo là một đoạn mã nhỏ tồn tại trong bất kỳ chương trình Windows gốc nào. Đại khái là như thế này:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
API GetMessage () Win32 truy xuất thông báo từ Windows. Chương trình của bạn thường dành 99,9% thời gian ở đó, đợi Windows cho biết điều gì đó thú vị đã xảy ra. TranslateMessage () là một hàm trợ giúp dịch các tin nhắn trên bàn phím. DispatchMessage () đảm bảo rằng thủ tục cửa sổ được gọi với thông báo.
Mỗi chương trình .NET được kích hoạt GUI đều có một vòng lặp thông báo, nó được khởi động bởi Application.Run ().
Sự liên quan của vòng lặp thông báo với Office có liên quan đến COM. Các chương trình Office là các chương trình hỗ trợ COM, đó là cách hoạt động của các lớp Microsoft.Office.Interop. COM đảm nhận việc phân luồng thay cho lớp COM, nó đảm bảo rằng các cuộc gọi được thực hiện trên giao diện COM luôn được thực hiện từ đúng luồng. Hầu hết các lớp COM có một khóa đăng ký trong sổ đăng ký khai báo ThreadingModel của chúng, cho đến nay các lớp phổ biến nhất (bao gồm cả Office) sử dụng "Căn hộ". Có nghĩa là cách an toàn duy nhất để gọi một phương thức giao diện là thực hiện cuộc gọi từ cùng một luồng đã tạo đối tượng lớp. Hay nói một cách khác: cho đến nay hầu hết các lớp COM đều không an toàn cho luồng.
Mỗi chuỗi được kích hoạt COM thuộc về một căn hộ COM. Có hai loại, Căn hộ đơn luồng (STA) và Căn hộ đa luồng (MTA). Một lớp COM theo luồng căn hộ phải được tạo trên một luồng STA. Bạn có thể thấy điều này trong các chương trình .NET, điểm nhập của chuỗi giao diện người dùng của chương trình Windows Forms hoặc WPF có thuộc tính [STAThread]. Mô hình căn hộ cho các luồng khác được đặt bởi phương thức Thread.SetApartmentState ().
Các phần lớn của hệ thống ống nước Windows sẽ không hoạt động chính xác nếu chuỗi giao diện người dùng không phải là STA. Đáng chú ý là Kéo + Thả, khay nhớ tạm, hộp thoại Windows như OpenFileDialog, các điều khiển như WebBrowser, ứng dụng UI Automation như trình đọc màn hình. Và nhiều máy chủ COM, như Office.
Một yêu cầu khó đối với một luồng STA là nó không bao giờ được chặn và phải bơm một vòng lặp bản tin. Vòng lặp thông báo rất quan trọng vì đó là những gì COM sử dụng để điều khiển một cuộc gọi phương thức giao diện từ một luồng này sang một luồng khác. Mặc dù .NET làm cho các cuộc gọi sắp xếp sao chép dễ dàng (ví dụ: Control.BeginInvoke hoặc Dispatcher.BeginInvoke), nó thực sự là một việc rất khó thực hiện. Luồng thực hiện cuộc gọi phải ở trạng thái nổi tiếng. Bạn không thể chỉ tùy tiện ngắt một luồng và buộc nó thực hiện một cuộc gọi phương thức, điều đó sẽ gây ra các vấn đề về sự hấp dẫn lại khủng khiếp. Một luồng phải ở trạng thái "nhàn rỗi", không bận thực thi bất kỳ mã nào làm thay đổi trạng thái của chương trình.
Có lẽ bạn có thể thấy điều đó dẫn đến đâu: vâng, khi một chương trình đang thực hiện vòng lặp thông báo, nó sẽ không hoạt động. Việc sắp xếp thực sự diễn ra thông qua một cửa sổ ẩn mà COM tạo ra, nó sử dụng PostMessage để thủ tục cửa sổ của cửa sổ đó thực thi mã. Trên chuỗi STA. Vòng lặp thông báo đảm bảo rằng mã này chạy.