STAThread 和多线程

来自 MSDN 关于 STAThread 的文章:

指示应用程序的 COM 线程模型为单线程单元(STA)。

(作为参考,这是 整篇文章。)

单线公寓... 好吧,我没想到。另外,我在某处读到,除非您的应用程序使用 COM 互操作,否则该属性实际上什么也不做。那么它到底是做什么的,它是如何影响多线程应用程序的呢?多线程应用程序(包括从使用 Timer的任何人到异步方法调用的任何东西,而不仅仅是线程池等等)是否应该使用 MTAThread,即使它“只是为了安全”?STAThread 和 MTAThread 实际上做什么?

82622 次浏览

What that does it it ensures that CoInitialize is called specifying COINIT_APARTMENTTHREADED as the parameter. If you do not use any COM components or ActiveX controls it will have no effect on you at all. If you do then it's kind of crucial.

Controls that are apartment threaded are effectively single threaded, calls made to them can only be processed in the apartment that they were created in.

Some more detail from MSDN:

Objects created in a single-threaded apartment (STA) receive method calls only from their apartment's thread, so calls are serialized and arrive only at message-queue boundaries (when the Win32 function PeekMessage or SendMessage is called).

Objects created on a COM thread in a multithread apartment (MTA) must be able to receive method calls from other threads at any time. You would typically implement some form of concurrency control in a multithreaded object's code using Win32 synchronization primitives such as critical sections, semaphores, or mutexes to help protect the object's data.

When an object that is configured to run in the neutral threaded apartment (NTA) is called by a thread that is in either an STA or the MTA, that thread transfers to the NTA. If this thread subsequently calls CoInitializeEx, the call fails and returns RPC_E_CHANGED_MODE.

Apartment threading is a COM concept; if you're not using COM, and none of the APIs you call use COM "under the covers", then you don't need to worry about apartments.

If you do need to be aware of apartments, then the details can get a little complicated; a probably-oversimplified version is that COM objects tagged as STA must be run on an STAThread, and COM objects marked MTA must be run on an MTA thread. Using these rules, COM can optimize calls between these different objects, avoiding marshaling where it isn't necessary.

STAThread is written before the Main function of a C# GUI Project. It does nothing but allows the program to create a single thread.