简体   繁体   English

STAThread和多线程

[英]STAThread and multithreading

From the MSDN article on STAThread: 来自有关STAThread的MSDN文章:

Indicates that the COM threading model for an application is single-threaded apartment (STA). 表示应用程序的COM线程模型是单线程单元(STA)。

(For reference, that's the entire article .) (作为参考,这是整篇文章 。)

Single-threaded apartment... OK, that went over my head. 单线程公寓......好吧,我的头脑。 Also, I read somewhere that unless your application uses COM interop, this attribute actually does nothing at all. 另外,我在某处读到,除非你的应用程序使用COM互操作,否则这个属性实际上什么都不做。 So what exactly does it do, and how does it affect multithreaded applications? 那究竟它究竟做了什么,以及它如何影响多线程应用程序? Should multithreaded applications (which includes anything from anyone using Timer s to asynchronous method calls, not just threadpools and the like) use MTAThread, even if it's 'just to be safe'? 多线程应用程序(包括使用Timer的任何人进行异步方法调用,而不仅仅是线程池等)都应该使用MTAThread,即使它“只是为了安全”? What does STAThread and MTAThread actually do? STAThread和MTAThread实际上做了什么?

Apartment threading is a COM concept; 公寓穿线是COM的概念; 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. 如果您没有使用COM,并且您调用的API都没有“使用COM”,那么您无需担心公寓。

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. 一个可能过于简单的版本是标记为STA的COM对象必须在STAThread上运行,标记为MTA的COM对象必须在MTA线程上运行。 Using these rules, COM can optimize calls between these different objects, avoiding marshaling where it isn't necessary. 使用这些规则,COM可以优化这些不同对象之间的调用,从而避免在不必要的地方进行编组。

What that does it it ensures that CoInitialize is called specifying COINIT_APARTMENTTHREADED as the parameter. 这样做可以确保调用CoInitialize指定COINIT_APARTMENTTHREADED作为参数。 If you do not use any COM components or ActiveX controls it will have no effect on you at all. 如果您不使用任何COM组件或ActiveX控件,它将对您没有任何影响。 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: 来自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). 在单线程单元(STA)中创建的对象仅从其单元的线程接收方法调用,因此调用被序列化并且仅到达消息队列边界(当调用Win32函数PeekMessage或SendMessage时)。

Objects created on a COM thread in a multithread apartment (MTA) must be able to receive method calls from other threads at any time. 在多线程单元(MTA)中的COM线程上创建的对象必须能够随时从其他线程接收方法调用。 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. 您通常会使用Win32同步原语(如关键部分,信号量或互斥锁)在多线程对象的代码中实现某种形式的并发控制,以帮助保护对象的数据。

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. 当配置为在中性线程单元(NTA)中运行的对象由STA或MTA中的线程调用时,该线程将传输到NTA。 If this thread subsequently calls CoInitializeEx, the call fails and returns RPC_E_CHANGED_MODE. 如果此线程随后调用CoInitializeEx,则调用将失败并返回RPC_E_CHANGED_MODE。

STAThread is written before the Main function of a C# GUI Project. STAThread是在C#GUI项目的Main函数之前编写的。 It does nothing but allows the program to create a single thread. 它什么都不做,只允许程序创建一个单独的线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM