C# STAThread 和多线程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/165316/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
STAThread and multithreading
提问by Matthew Scharley
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. 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'? What does STAThread and MTAThread actually do?
单线程公寓......好吧,这超出了我的脑海。另外,我在某处读到,除非您的应用程序使用 COM 互操作,否则此属性实际上什么也不做。那么它究竟做了什么,它又如何影响多线程应用程序呢?多线程应用程序(包括使用Timer
s 到异步方法调用的任何人,而不仅仅是线程池等)是否应该使用 MTAThread,即使它“只是为了安全”?STAThread 和 MTAThread 实际上是做什么的?
采纳答案by Bruce
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.
单元线程是一个 COM 概念;如果您不使用 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. Using these rules, COM can optimize calls between these different objects, avoiding marshaling where it isn't necessary.
如果您确实需要了解公寓,那么细节可能会变得有点复杂;一个可能过于简化的版本是标记为 STA 的 COM 对象必须在 STAThread 上运行,而标记为 MTA 的 COM 对象必须在 MTA 线程上运行。使用这些规则,COM 可以优化这些不同对象之间的调用,避免不必要的封送处理。
回答by 1800 INFORMATION
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.
它的作用是确保CoInitialize
将 COINIT_APARTMENTTHREADED 指定为参数。如果您不使用任何 COM 组件或 ActiveX 控件,它将对您没有任何影响。如果你这样做,那么它是至关重要的。
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).
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.
在单线程单元 (STA) 中创建的对象仅从其单元的线程接收方法调用,因此调用被序列化并且仅到达消息队列边界(当调用 Win32 函数 PeekMessage 或 SendMessage 时)。
在多线程单元 (MTA) 中的 COM 线程上创建的对象必须能够随时接收来自其他线程的方法调用。您通常会使用 Win32 同步原语(例如临界区、信号量或互斥锁)在多线程对象的代码中实现某种形式的并发控制,以帮助保护对象的数据。
当 STA 或 MTA 中的线程调用配置为在中性线程单元 (NTA) 中运行的对象时,该线程将传输到 NTA。如果此线程随后调用 CoInitializeEx,则调用失败并返回 RPC_E_CHANGED_MODE。
回答by Zeinth
STAThread is written before the Main function of a C# GUI Project. It does nothing but allows the program to create a single thread.
STAThread 写在 C# GUI 项目的 Main 函数之前。它只允许程序创建单个线程。