选择线程模型

为对象选择线程模型取决于对象的函数。 执行大量 I/O 的对象可能支持自由线程处理,通过允许在 I/O 延迟期间调用接口来向客户端提供最大响应。 另一方面,与用户交互的对象可能支持单元线程,以同步传入 COM 调用及其窗口操作。

支持单线程单元单元中的单元线程更轻松,因为 COM 基于每个调用提供同步。 支持自由线程处理更加困难,因为对象必须实现同步;但是,对客户端的响应可能更好,因为可以针对较小的代码部分实现同步。

Tip

COM 客户端的快速决策指南:

// UI thread or main thread with a message loop → STA
HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

// Background/worker thread with no message loop → MTA
HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);

对于 COM 服务器(进程内 DLL),请在 InprocServer32 键下将 ThreadingModel 设置为注册表值:

  • Apartment — 对象在调用方 STA 中运行(与 UI 相关的对象最常见)
  • Free — 对象在 MTA 中运行
  • Both - 对象在调用方的公寓中运行(最适合通用对象)
  • Neutral — 对象在中性单元(仅 COM+)中运行

如果不确定,请先使用 Both,并确保对象是线程安全的。 这通过让 COM 在调用方的单元中创建对象来减少跨单元封送,尽管对于跨单元回调或从其他单元访问仍可能发生封送。

跨公寓访问接口

多线程公寓

进程内服务器线程问题

进程、线程和单元

单线程和多线程通信

单线程单元