2011-01-11 32 views
17

Khi bạn tạo một ứng dụng rỗng WinForms với Visual Studio, mẫu có thuộc tính STAThread trong lớp ứng dụng chính.Tại sao các ứng dụng WinForms STAThread theo mặc định?

Tôi đã đọc một số tài liệu về nó, nhưng tôi không chắc liệu tôi có hiểu nó hay không.

Thực sự tôi có một số câu hỏi về nó:

  1. Tại sao thuộc tính này thêm vào?
  2. Có nghĩa là gì?
  3. Điều gì xảy ra nếu bạn xóa thuộc tính này?
+2

Có thể trùng lặp: http://stackoverflow.com/questions/102437/why-do-all-winforms-programs-require-the-stathread-attribute –

+0

@Cody: Vâng, xin lỗi, tôi không thấy, nhưng IMHO câu trả lời này tốt hơn nhiều so với câu trả lời khác. –

+1

Vâng, đó là công bằng. Tôi không bỏ phiếu để đóng vì những câu trả lời đó không tuyệt vời. Các bit quan trọng nhất của kiến ​​thức để thu thập từ câu hỏi đó là liên kết này: http://blogs.msdn.com/b/jfoscoding/archive/2005/04/07/406341.aspx –

Trả lời

12

1. Tại sao thuộc tính này được thêm?

Do mô hình đối tượng ActiveX yêu cầu. Và bạn có thể thả các điều khiển ActiveX trên một WinForm (vì vậy nó có khả năng tương thích) HOẶC một số lớp .NET sử dụng các điều khiển gốc yêu cầu thuộc tính đó.

2. Điều đó có nghĩa là gì?

Điều đó có nghĩa là chuỗi chạy trong single-threaded apartment model.

3. Điều gì sẽ xảy ra nếu bạn xóa thuộc tính này?

Nếu thuộc tính bị xóa, hành vi không xác định. Chương trình có thể thất bại một cách ngẫu nhiên, với các thông báo lỗi đôi khi hợp lý. Ví dụ: mọi thứ có thể hoạt động ngay bây giờ, sau đó ngắt với gói dịch vụ.

+1

Vấn đề lớn nhất bạn sẽ gặp phải là COM interop. Và đừng nói rằng bạn không làm điều này và không quan tâm — Windows thực hiện rất nhiều điều đó dưới sự bảo hiểm. –

+0

Ít nhất WPF từ chối làm việc ngay cả trong MTA và đưa ra một ngoại lệ ngay lập tức. Có thể là WinForms làm điều đó, quá. – Joey

+1

Nó không chỉ là điều khiển ActiveX, rất nhiều thứ khác phụ thuộc vào nó. Clipboard, Kéo + Thả, bất kỳ hộp thoại vỏ nào như OpenFileDialog. Thêm rất nhiều trình bao bọc .NET sử dụng API COM bên dưới nắp. Đó là tất cả các interop COM mà bạn không thể nhìn thấy nhưng chỉ hoạt động đúng trong một thread STA. Ngay cả khi CLR nhận thức được nó, Thread.Join() bơm một vòng lặp tin nhắn ví dụ khi được gọi trên một chuỗi giao diện người dùng. –

19

Để trích dẫn từ an MSDN blog,

Khi STAThreadAttribute được áp dụng, nó thay đổi trạng thái căn hộ của thread hiện hành là đơn luồng. Nếu không nhận được vào một cuộc thảo luận rất lớn về COM và luồng, thuộc tính này đảm bảo cơ chế giao tiếp giữa các chủ đề hiện tại và các chủ đề khác mà có thể muốn nói chuyện với nó thông qua COM. Khi bạn đang sử dụng Windows Forms, tùy thuộc vào tính năng bạn đang sử dụng, nó có thể đang sử dụng COM interop để giao tiếp với các thành phần của hệ điều hành. Ví dụ điển hình là Clipboard và Hộp thoại Tệp.

+0

Sẽ rất tuyệt nếu bạn đặt liên kết tới blog trong câu trả lời của mình. – GEOCHET

0

Điều đó có nghĩa là các chương trình Windows Forms sử dụng trạng thái căn hộ đơn luồng. MTA và các trạng thái căn hộ có ren miễn phí không được hỗ trợ.

3

3.Điều gì sẽ xảy ra nếu bạn xóa thuộc tính này?

Tôi chỉ thêm một ví dụ đơn giản thể hiện sự cố.

Tôi đã tạo ứng dụng WinForms đơn giản bằng nút và OpenFileDialog. Khi nhấn nút, tôi chạy một chuỗi chỉ ra openFileDialog. Tôi khởi động ứng dụng có và không có STAThread và kết quả của việc nhấp vào nút giống nhau - nó ném ngoại lệ "Thao tác chéo không hợp lệ: Kiểm soát 'Form1' được truy cập từ một chuỗi khác với chuỗi được tạo trên". Có vẻ như không có sự khác biệt. Nhưng không.

Sau đó, tôi đã thay đổi hiển thị OpenFileDialog bằng cách gọi phương pháp dưới đây:

private void ShowOFD() 
{ 
    if (InvokeRequired) 
    { 
     BeginInvoke(new Action(ShowOFD)); 
     return; 
    } 

    openFileDialog1.ShowDialog(this); 
} 

Với STAThread nó hoạt động tốt như mong đợi. Nếu không có STAThread nó ném ngoại lệ: "Chủ đề hiện tại phải được đặt thành chế độ căn hộ đơn lẻ (STA) trước khi có thể thực hiện các cuộc gọi OLE. Đảm bảo rằng chức năng chính của bạn có STAThreadAttribute được đánh dấu trên đó. cho quá trình ".

Sau đó, tôi khởi chạy ứng dụng nhiều lần mà không cần trình gỡ lỗi (tách ra khỏi studio trực quan). Một lần ứng dụng chỉ đóng lặng lẽ, một lần khác ứng dụng đóng với thông báo "vshost đã ngừng hoạt động"

Các vấn đề liên quan