你能用你自己的话解释一下STA和MTA吗?

另外,什么是公寓线程,它们只与COM有关吗?如果有,为什么?


当前回答

STA(单线程公寓)的基本概念是,一次只有一个线程与您的代码交互。打到你公寓的电话是通过窗口消息(使用一个不可见的)窗口编组的。这允许调用排队等待操作完成。

MTA(多线程公寓)是许多线程可以同时操作的地方,作为开发人员的您有责任处理线程安全性。

关于COM中的线程模型还有很多需要学习的地方,但是如果你在理解它们是什么方面有困难,那么我会说理解STA是什么以及它是如何工作的将是最好的起点,因为大多数COM对象都是STA的。

公寓线程,如果一个线程和它正在使用的对象住在同一个公寓,那么它就是公寓线程。我认为这只是一个COM概念,因为它只是谈论与它们交互的对象和线程的一种方式……

其他回答

Side note: If you are using some PowerShell 2.0 snap-ins, you need to launch PowerShell version 3 or greater with -MTA option to use them. PowerShell 2 apartment model is MTA versus later versions use STA as default. Other point is bitness. Normal calls in apartment are not marshalled (direct calls), so if your caller is x64 then callee must be also x64. Only way around this is to use remote procedure call (RPC), which add huge amount of overhead (spawn a new 32-bit process to load snap-in DLL and query result by some means).For developer: always publish type library - it make your COM object discovery and usage much easier! Every interface should be public and unique - implementation can be proprietary or open source.

另一种情况

例子:

 IStorage_vtbl** reference; // you got it by some means of factory
 
 
 public unsafe int OpenStorage(char* pwcsName, IStorage pstgPriority, uint grfMode, char** snbExclude, uint reserved, IStorage* ppstg)
 {
     IStorage_vtbl** @this = (IStorage_vtbl**)reference;
     IStorage_vtbl* vtbl = *@this;
     if (vtbl == null)
         throw new InvalidComObjectException();
     Delegate genericDelegate = Marshal.GetDelegateForFunctionPointer(vtbl->method_6, typeof(delegate_6));
     delegate_6 method = (delegate_6)genericDelegate;
     return method(@this, pwcsName, pstgPriority, grfMode, snbExclude, reserved, ppstg);
 }
 

这段代码只是为COM子系统的实际调用添加了“This”指针 那么,这个调用是打开IStorage STA或MTA的实例吗?

调用COM对象dll的代码(例如,读取私有数据文件)可能在用户界面中正常工作,但却神秘地挂在服务上。原因是。net 2.0的用户界面假设是STA(线程安全的),而服务假设是MTA((在此之前,服务假设是STA)。必须为服务中的每个COM调用创建一个STA线程会增加大量开销。

STA(单线程公寓)的基本概念是,一次只有一个线程与您的代码交互。打到你公寓的电话是通过窗口消息(使用一个不可见的)窗口编组的。这允许调用排队等待操作完成。

MTA(多线程公寓)是许多线程可以同时操作的地方,作为开发人员的您有责任处理线程安全性。

关于COM中的线程模型还有很多需要学习的地方,但是如果你在理解它们是什么方面有困难,那么我会说理解STA是什么以及它是如何工作的将是最好的起点,因为大多数COM对象都是STA的。

公寓线程,如果一个线程和它正在使用的对象住在同一个公寓,那么它就是公寓线程。我认为这只是一个COM概念,因为它只是谈论与它们交互的对象和线程的一种方式……

每个承载COM或OLE控件的EXE都定义了它的单元状态。单元状态默认为STA(对于大多数程序应该是STA)。

STA -所有OLE控件必须位于STA中。STA意味着你的com对象必须总是在UI线程上操作,不能传递给其他线程(就像MFC中的任何UI元素一样)。但是,您的程序仍然可以有许多线程。

MTA -你可以在程序中的任何线程上操作COM对象。

这篇文章很清楚地解释了STA和MTA。

了解COM公寓,第一部分 理解COM公寓,第二部分

关于什么是Apartment的要点:

An apartment is a concurrency boundary; it’s an imaginary box drawn around objects and client threads that separates COM clients and COM objects that have incompatible threading characteristics. Every thread that uses COM, and every object that those threads create, is assigned to an apartment. When a thread calls COM’s CoInitialize or CoInitializeEx function, that thread is placed in an apartment. And when an object is created, it too is placed in an apartment. Whenever it creates a new apartment, COM allocates an apartment object on the heap and initializes it with important information such as the apartment ID and apartment type. When it assigns a thread to an apartment, COM records the address of the corresponding apartment object in thread-local storage (TLS).