Co robi [STAThread]?

293

Uczę się C # 3.5 i chcę wiedzieć, co [STAThread]robi w naszych programach?

odiseh
źródło

Odpowiedzi:

240

Jest STAThreadAttributeto zasadniczo wymóg, aby pompa komunikatów systemu Windows komunikowała się ze składnikami COM. Chociaż podstawowe formularze Windows Forms nie używają COM, wiele składników systemu operacyjnego, takich jak okna dialogowe systemu, korzysta z tej technologii.

MSDN wyjaśnia przyczynę nieco bardziej szczegółowo:

STAThreadAttribute wskazuje, że model wątków COM dla aplikacji jest jednowątkowy. Ten atrybut musi być obecny w punkcie wejścia każdej aplikacji korzystającej z formularzy Windows; jeśli zostanie pominięty, składniki systemu Windows mogą nie działać poprawnie. Jeśli ten atrybut nie jest obecny, aplikacja korzysta z wielowątkowego modelu mieszkania, który nie jest obsługiwany w formularzach Windows Forms.

Ten post na blogu ( Dlaczego wymagany jest STAThread? ) Również dość dobrze wyjaśnia ten wymóg. Jeśli chcesz uzyskać bardziej szczegółowe informacje o tym, jak działa model gwintowania na poziomie CLR, zapoznaj się z tym artykułem MSDN Magazine z czerwca 2004 r. (Archiwum, kwiecień 2009).

Noldorin
źródło
1
jakiś pomysł, dlaczego CompactFramework nie obsługuje [STAThread]?
bvdb
1
stackoverflow.com/questions/4154429/apartmentstate-for-dummies ta odpowiedź jest całkiem zrozumiała dla śmiertelników takich jak ja. Dodano tylko dla odniesienia tutaj
Barış Akkurt
41

Mówi kompilatorowi, że jesteś w modelu apartamentu z jednym wątkiem. Jest to zła rzecz COM, jest zwykle używana w Windows Forms (GUI), ponieważ używa ona Win32 do rysowania, który jest zaimplementowany jako STA. Jeśli używasz czegoś, co jest modelem STA z wielu wątków, otrzymujesz uszkodzone obiekty.

Dlatego musisz wywoływać Gui z innego wątku (jeśli wykonałeś kodowanie formularzy).

Zasadniczo nie przejmuj się tym, po prostu zaakceptuj, że wątki GUI systemu Windows muszą być oznaczone jako STA, w przeciwnym razie zdarzają się dziwne rzeczy.

Spence
źródło
2
STAThread nie ma nic wspólnego z wymogiem wywołania głównego wątku podczas uzyskiwania dostępu do GUI. Wynika to po prostu z natury pompy komunikatów systemu Windows i nie można jej bardziej ogólnie uniknąć w aplikacjach wielowątkowych.
Noldorin
3
Naprawdę chodzi tylko o obsługę komponentów COM, takich jak okna dialogowe systemu operacyjnego i komponenty innych firm.
Noldorin
3
Win32 nie ma pojęcia wątków mieszkań, jego COM, który wprowadza tę koncepcję. COM „ponownie wykonuje zadania”, co było całkowicie wątkowym systemem agnostycznym (pompa komunikatów systemu Windows) jako sposób synchronizacji / serializacji wykonania kodu w mieszkaniach COM.
AnthonyWJones
1
Po prostu zaakceptuj, że guady Windowsa muszą być oznaczone jako STA, w przeciwnym razie zdarzają się dziwne rzeczy. :))))))
Nipuna
1
@Noldorin „wymóg wywołania głównego wątku” - nie jest to technicznie wymagane . Wyjątki między wątkami nie występują poza debuggerem. Ref: stackoverflow.com/questions/3972727/... . Nie oznacza to jednak, że nie powinieneś rozwiązać tego problemu!
Shiv
31

STAThreadAttribute oznacza wątek, który będzie używał jedno-wątkowego apartamentu COM, jeśli COM jest potrzebny. Domyślnie .NET w ogóle nie inicjuje COM. Tylko wtedy, gdy potrzebny jest COM, np. Gdy tworzony jest obiekt COM lub kontrolka COM lub gdy potrzebne jest przeciąganie i upuszczanie, COM jest inicjowany. Kiedy tak się dzieje, .NET wywołuje podstawową funkcję CoInitializeEx, która pobiera flagę wskazującą, czy dołączyć wątek do mieszkania wielowątkowego czy jednowątkowego.

Przeczytaj więcej informacji tutaj (zarchiwizowane, czerwiec 2009)

i

Dlaczego wymagany jest STAThread?

Rahul
źródło