STAThread和multithreading

从MSDN文章STAThread:

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

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

单线程的公寓…好吧,那就超过了我的头。 另外,我读了一个地方,除非你的应用程序使用COM互操作,这个属性实际上什么都不做。 那么它究竟做了什么,它如何影响multithreading应用程序呢? 如果multithreading应用程序(包括任何使用Timers的asynchronous方法调用,而不仅仅是线程池等)都使用MTAThread,即使它只是为了安全起见。 STAThread和MTAThread实际上做了什么?

公寓线程是一个COM概念, 如果你不使用COM,也没有你调用的API使用COM“在封面下”,那么你不需要担心公寓。

如果你确实需要了解公寓,那么细节就会变得复杂一些 。 一个可能过度简化的版本是标记为STA的COM对象必须在STAThread上运行,并且标记为MTA的COM对象必须在MTA线程上运行。 使用这些规则,COM可以优化这些不同对象之间的调用,从而避免在不必要的地方编组。

这样做确保CoInitialize被调用指定COINIT_APARTMENTTHREADED作为参数。 如果你不使用任何COM组件或者ActiveX控件,那么它根本不会对你产生任何影响。 如果你这样做,这是至关重要的。

控制单元实际上是单线程的,对它们的调用只能在创build它们的单元中进行处理。

来自MSDN的更多细节:

在单线程单元(STA)中创build的对象只能从其公寓线程接收方法调用,因此调用将被序列化,并且仅在消息队列边界(当调用Win32函数PeekMessage或SendMessage时)到达。

在multithreading单元(MTA)中的一个COM线程上创build的对象必须能够随时接收来自其他线程的方法调用。 您通常会使用Win32同步原语(如临界区,信号量或互斥体)在multithreading对象的代码中实现某种forms的并发控制,以帮助保护对象的数据。

当configuration为在中性线程单元(NTA)中运行的对象由STA或MTA中的线程调用时,该线程将转移到NTA。 如果此线程随后调用CoInitializeEx,则调用失败并返回RPC_E_CHANGED_MODE。

STAThread写在C#GUI项目的Main函数之前。 它什么都不做,只能让程序创build一个线程。