Câu trả lời:
Về STAThreadAttribute
cơ bản, đây là một yêu cầu để bơm thông báo Windows giao tiếp với các thành phần COM. Mặc dù Windows Forms lõi không sử dụng COM, nhiều thành phần của HĐH như hộp thoại hệ thống sử dụng công nghệ này.
MSDN giải thích lý do chi tiết hơn một chút:
STAThreadAttribution chỉ ra rằng mô hình luồng COM cho ứng dụng là căn hộ đơn luồng. Thuộc tính này phải có mặt trên điểm vào của bất kỳ ứng dụng nào sử dụng Windows Forms; nếu nó bị bỏ qua, các thành phần Windows có thể không hoạt động chính xác. Nếu không có thuộc tính, ứng dụng sẽ sử dụng mô hình căn hộ đa luồng, không được hỗ trợ cho Windows Forms.
Bài đăng trên blog này ( Tại sao STAThread được yêu cầu? ) Cũng giải thích yêu cầu này khá tốt. Nếu bạn muốn có một cái nhìn sâu hơn về cách thức hoạt động của mô hình luồng ở cấp độ CLR, hãy xem bài viết của Tạp chí MSDN này từ tháng 6 năm 2004 (Lưu trữ, tháng 4 năm 2009).
Nó báo cho trình biên dịch rằng bạn đang ở trong một mô hình Căn hộ một luồng. Đây là một điều COM xấu, nó thường được sử dụng cho Windows Forms (GUI) vì nó sử dụng Win32 cho bản vẽ của nó, được triển khai dưới dạng STA. Nếu bạn đang sử dụng mô hình STA nào đó từ nhiều luồng thì bạn sẽ nhận được các đối tượng bị hỏng.
Đây là lý do tại sao bạn phải gọi Gui từ một luồng khác (nếu bạn đã thực hiện bất kỳ hình thức mã hóa nào).
Về cơ bản, đừng lo lắng về điều đó, chỉ cần chấp nhận rằng các luồng Windows GUI phải được đánh dấu là STA nếu không có những điều kỳ lạ xảy ra.
STAThreadAttribution đánh dấu một chủ đề để sử dụng Căn hộ COM đơn luồng nếu cần COM. Theo mặc định, .NET sẽ không khởi tạo COM cả. Chỉ khi COM là cần thiết, như khi đối tượng COM hoặc Điều khiển COM được tạo hoặc khi cần kéo thả, COM đó được khởi tạo. Khi điều đó xảy ra, .NET gọi hàm CoInitializeEx nằm bên dưới, sẽ lấy một cờ cho biết liệu có nên nối luồng với căn hộ đa luồng hoặc đơn luồng hay không.
Đọc thêm thông tin ở đây (Lưu trữ, tháng 6 năm 2009)
và
[STAThread]
?