从STAThread上的MSDN文章中:
指示应用程序的COM线程模型是单线程单元(STA)。
(供参考,这是整篇文章。)
单线程公寓...好吧,这让我头疼。另外,我在某处读到,除非您的应用程序使用COM互操作,否则此属性实际上什么都不做。那么它到底是做什么的,又如何影响多线程应用程序呢?Timer
即使“为了安全”,多线程应用程序(包括使用s的任何人到异步方法调用,而不仅仅是线程池之类的东西)都应该使用MTAThread吗?STAThread和MTAThread实际做什么?
从STAThread上的MSDN文章中:
指示应用程序的COM线程模型是单线程单元(STA)。
(供参考,这是整篇文章。)
单线程公寓...好吧,这让我头疼。另外,我在某处读到,除非您的应用程序使用COM互操作,否则此属性实际上什么都不做。那么它到底是做什么的,又如何影响多线程应用程序呢?Timer
即使“为了安全”,多线程应用程序(包括使用s的任何人到异步方法调用,而不仅仅是线程池之类的东西)都应该使用MTAThread吗?STAThread和MTAThread实际做什么?
Answers:
单元线程是COM概念。如果您不使用COM,并且您调用的所有API都不在“幕后”使用COM,那么您就不必担心公寓。
如果您确实需要注意公寓,那么细节可能会有些复杂;一个可能过于简化的版本是,标记为STA的COM对象必须在STAThread上运行,标记为MTA的COM对象必须在MTA线程上运行。使用这些规则,COM可以优化这些不同对象之间的调用,从而避免在不必要的地方进行封送处理。
它所做的是确保CoInitialize
将COINIT_APARTMENTTHREADED指定为参数被调用。如果您不使用任何COM组件或ActiveX控件,则对您完全没有影响。如果您这样做,那将很关键。
单元线程的控件实际上是单线程的,对它们的调用只能在创建它们的单元中处理。
来自MSDN的更多详细信息:
在单线程单元(STA)中创建的对象仅从其单元的线程接收方法调用,因此调用被序列化,并且仅到达消息队列边界(调用Win32函数PeekMessage或SendMessage时)。
在多线程单元(MTA)的COM线程上创建的对象必须能够随时接收来自其他线程的方法调用。通常,您将使用Win32同步原语(例如关键部分,信号量或互斥体)在多线程对象的代码中实现某种形式的并发控制,以帮助保护对象的数据。
当被配置为在中性线程单元(NTA)中运行的对象被STA或MTA中的线程调用时,该线程将转移到NTA。如果此线程随后调用CoInitializeEx,则调用将失败并返回RPC_E_CHANGED_MODE。
CoInitialize()
以响应STAThread
属性/ ApartmentState
吗?注意:有关MSDN的文章在这里:CoInitializeEx函数。
CoInitialize()
内部使用?我一直跟踪STAThread属性,但是踪迹变得很冷(我找不到的来源Thread::SetApartment
)。是否在任何地方记录了thread.h(COM thread.h)中的Thread类?是MFC,ATL还是其他?