托管和非托管线程处理

COM 组件使用单元来同步对资源的访问。 与之相对,托管对象使用同步区域、同步基元和同步上下文来确保以线程安全的方式使用所有共享资源,其中同步基元指互斥体、锁和完成端口等对象。 有关 .NET 线程模型的其他信息,请参见托管线程处理

为了实现互用性,公共语言运行时将在调用 COM 对象时创建一个单元并将其初始化。 托管线程可以创建并进入只包含一个线程的单线程单元 (STA) 或包含一个或多个线程的多线程单元 (MTA)。 当 COM 单元与线程所生成的单元兼容时,COM 将允许调用线程直接调用 COM 对象。 如果这两种单元不兼容,COM 将创建一个兼容的单元并通过代理将所有调用封送在新的单元中。

运行时调用 CoInitializeEx 将 COM 单元初始化为 MTA 或 STA 单元。 在 .NET Framework 2.0 版中,如果未在启动线程之前设置托管线程的单元状态,则托管线程会被初始化为 MTA。 在启动线程之前可使用 SetApartmentStateTrySetApartmentState 方法设置单元状态。

在 .NET Framework 2.0 版中,除非将 STAThreadAttribute 应用于入口点过程,否则主应用程序线程会被初始化为 MTA

注意注意

在 .NET Framework 1.0 和 1.1 版中,可以通过使用 System.Threading.ApartmentState 属性在线程运行之后设置单元状态;这样会创建争用条件。在 .NET Framework 2.0 版中,这是不允许的。

某些编程模型要求为线程设置 STA 属性。 例如,要使 Windows 窗体初始化诸如拖放这样的元素,必须创建并输入一个单线程单元。

注意注意

如果既未注册代理及存根 (stub),也未注册类型库,当从托管代码调用 COM 对象时,会发生 InvalidCastException

下表将列出 ApartmentState 枚举值并显示可比的 COM 单元初始化调用。

ApartmentState 枚举值

COM 单元初始化

MTA

CoInitializeEx(NULL, COINIT_MULTITHREADED)

STA

CoIntializeEx(NULL, COINIT_APARTMENTTHREADED)

未知

CoInitializeEx(NULL, COINIT_MULTITHREADED)

只要 COM 对象和托管线程处于不兼容的单元中,对该对象的所有调用都将通过由 COM 创建的代理来进行。

请参见

概念

向 .NET Framework 公开 COM 组件

向 COM 公开 .NET Framework 组件

其他资源

高级 COM 互操作性