STAThread和多线程
时间:2020-03-06 15:03:28 来源:igfitidea点击:
从STAThread上的MSDN文章中:
Indicates that the COM threading model for an application is single-threaded apartment (STA).
(供参考,这是整篇文章。)
单线程公寓...好吧,这让我头疼。另外,我在某处读到,除非应用程序使用COM互操作,否则此属性实际上什么都不做。那么它到底是做什么的,又如何影响多线程应用程序呢?即使是"为了安全",多线程应用程序(包括从使用"计时器"的任何人到异步方法调用的任何东西,而不仅仅是线程池之类的东西)都应该使用MTAThread吗? STAThread和MTAThread实际做什么?
解决方案
它的作用是确保以指定COINIT_APARTMENTTHREADED作为参数来调用CoInitialize
。如果我们不使用任何COM组件或者ActiveX控件,则对我们完全没有影响。如果我们这样做,那将很关键。
单元线程的控件实际上是单线程的,对它们的调用只能在创建它们的单元中处理。
来自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.
单元线程是COM概念。如果我们不使用COM,并且我们调用的所有API都不在"幕后"使用COM,那么我们就不必担心公寓。
如果我们确实需要注意公寓,那么细节可能会有些复杂。一个可能过于简化的版本是,标记为STA的COM对象必须在STAThread上运行,标记为MTA的COM对象必须在MTA线程上运行。使用这些规则,COM可以优化这些不同对象之间的调用,从而避免在不必要的地方进行封送处理。