你能解释一下STA和MTA吗?

你能用本身的话解释STA和MTA吗? 安全

什么是公寓线程,它们只与COM有关吗? 若是是这样,为何? 多线程


#1楼

每一个承载COM或OLE控件的EXE都定义它的公寓状态。 公寓状态默认为STA(而且对于大多数程序应该是STA)。 并发

STA - 必要时全部OLE控件必须位于STA中。 STA意味着必须始终在UI线程上操做COM对象,而且不能将其传递给其余线程(很是相似于MFC中的任何UI元素)。 可是,您的程序仍然能够有许多线程。 学习

MTA - 您能够在程序中的任何线程上操做COM对象。 spa


#2楼

COM线程模型称为“单元”模型,其中初始化COM对象的执行上下文与单个线程(单线程单元)或多个线程(多线程单元)相关联。 在此模型中,COM对象一旦在公寓中初始化,就会在其运行时间内成为该公寓的一部分。 线程

STA模型用于非线程安全的COM对象。 这意味着他们不会处理本身的同步。 这个的常见用途是UI组件。 所以,若是另外一个线程须要与对象交互(例如按下表单中的按钮),则将消息编组到STA线程上。 窗口造成消息泵系统就是一个例子。 设计

若是COM对象能够处理本身的同步,则可使用MTA模型,其中容许多个线程与对象交互而无需编组调用。 code


#3楼

STA(单线程单元)基本上是一次只有一个线程与您的代码交互的概念。 经过Windows消息(使用不可见的)窗口对您公寓的呼叫进行封送。 这容许调用排队并等待操做完成。 对象

MTA(多线程公寓)是许多线程能够同时运行的地方,做为开发人员负责处理线程安全性的责任在你身上。 进程

关于COM中的线程模型还有不少东西要学习,但若是你没法理解它们是什么,那么我会说理解STA是什么以及它是如何工做的将是最好的起点,由于大多数COM对象都是STA的。

Apartment Threads,若是一个线程与它正在使用的对象住在同一个公寓,那么它就是一个公寓线程。 我认为这只是一个COM概念,由于它只是一种谈论它们与之交互的对象和线程的方式......


#4楼

这彻底取决于如何处理对象的调用,以及他们须要多少保护。 COM对象能够要求运行时保护它们不被多个线程同时调用; 那些不能够从不一样线程同时调用,所以他们必须保护本身的数据。

此外,若是从用户界面线程进行调用,运行时还必须阻止COM对象调用阻止用户界面。

公寓是物品居住的地方,它们包含一个或多个线程。 公寓定义了拨打电话时会发生什么。 对公寓中的对象的调用将在该公寓中的任何线程上接收和处理,除了已经在正确的公寓中的线程的调用由其自身处理(即直接调用该对象)。

线程能够是单线程公寓(在这种状况下,它们是该公寓中惟一的线程)或多线程公寓。 它们指定线程为该线程初始化COM的时间。

STA主要用于与用户界面兼容,用户界面与特定线程相关联。 STA经过接收到隐藏窗口的窗口消息来接收处理呼叫的通知; 当它进行出站呼叫时,它会启动模态消息循环以防止处理其余窗口消息。 您能够指定要调用的消息过滤器,以便您的应用程序能够响应其余消息。

相比之下,全部MTA线程共享该进程的单个MTA。 若是没有可用的线程,COM能够启动一个新的工做线程来处理传入的调用,直到池限制。 进行出站呼叫的线程只是阻止。

为简单起见,咱们只考虑在DLL中实现的对象,经过为其类的键设置ThreadingModel值,在注册表中公布它们支持的内容。 有四种选择:

  • 主线程( ThreadingModel值不存在)。 该对象是在主机的主UI线程上建立的,而且全部调用都被编组到该线程。 只能在该线程上调用类工厂。
  • Apartment 。 这代表该类能够在任何单线程模式线程上运行。 若是建立它的线程是STA线程,则该对象将在该线程上运行,不然将在主STA中建立 - 若是不存在主STA,则将为其建立STA线程。 (这意味着建立Apartment对象的MTA线程将编组全部对不一样线程的调用。)类工厂能够由多个STA线程同时调用,所以它必须保护其内部数据不受此影响。
  • Free 这表示设计为在MTA中运行的类。 即便由STA线程建立,它也将始终加载到MTA中,这再次意味着STA线程的调用将被编组。 这是由于Free对象一般是在能够阻止的状况下编写的。
  • Both 。 这些类是灵活的,能够在任何建立它们的公寓中加载。 必须编写它们以知足两组要求,可是:它们必须保护它们的内部状态免受并发调用的影响,以防它们被加载到MTA中,可是若是它们被加载到STA中则不能阻塞。

从.NET Framework,基本上只在建立UI的任何线程上使用[STAThread] 。 工做线程应该使用MTA,除非他们打算使用带Apartment标记的COM组件,在这种状况下,若是从多个线程调用相同的组件,则使用STA以免编组开销和可伸缩性问题(由于每一个线程都必须等待对于组件反过来)。 若是你为每一个线程使用一个单独的COM对象,不管组件是在STA仍是MTA中,它都会更加容易。


#5楼

调用COM对象dll的代码(例如,读取专有数据文件)可能在用户界面中正常工做,但在服务中神秘地挂起。 缘由是.Net 2.0用户界面假设STA(线程安全),而服务假定MTA(在此以前,服务假设STA)。必须为服务中的每一个COM调用建立STA线程可能会增长显着的开销。

相关文章
相关标签/搜索