gpt4 book ai didi

.net - 在 .NET 中与 COM 交互之前是否需要调用 CoInitialize?

转载 作者:行者123 更新时间:2023-12-02 02:11:35 25 4
gpt4 key购买 nike

我知道每个线程调用 COM 的要求 CoInitialize在与 COM 系统交互之前。

.NET 公开了一些在线程上内部操作的项目,例如:

如果我要从线程与 COM 对象交互,我是否需要调用 CoInitialize首先?

我问是因为可能有一些more magic that automagically calls it for me - 我不知道。

<小时/>

奖励阅读

Managed and Unmanaged Threading

For interoperability, the common language runtime creates and initializes an apartment when calling a COM object. A managed thread can create and enter a single-threaded apartment (STA) that contains only one thread, or a multi-threaded apartment (MTA) that contains one or more threads. When a COM apartment and a thread-generated apartment are compatible, COM allows the calling thread to make calls directly to the COM object. If the apartments are incompatible, COM creates a compatible apartment and marshals all calls through a proxy in the new apartment.

The runtime calls CoInitializeEx to initialize the COM apartment as either an MTA or an STA apartment.

更新二:

看来您不应该从 .NET 可以提供的任何类型的线程中使用 COM:

The Managed Thread Pool

There are several scenarios in which it is appropriate to create and manage your own threads instead of using thread pool threads:

  • You require a foreground thread.

  • You require a thread to have a particular priority.

  • You have tasks that cause the thread to block for long periods of time. The thread pool has a maximum number of threads, so a large number of blocked thread pool threads might prevent tasks from starting.

  • You need to place threads into a single-threaded apartment. All ThreadPool threads are in the multithreaded apartment.

  • You need to have a stable identity associated with the thread, or to dedicate a thread to a task.

更新三:

看起来您可以设置非托管线程的线程模型:

Managed and Unmanaged Threading in Microsoft Windows

A managed thread can be marked to indicate that it will host a single-threaded or multithreaded apartment. The GetApartmentState, SetApartmentState, and TrySetApartmentState methods of the Thread class return and assign the apartment state of a thread. If the state has not been set, GetApartmentState returns ApartmentState.Unknown.

The property can be set only when the thread is in the ThreadState.Unstarted state; it can be set only once for a thread.

If the apartment state is not set before the thread is started, the thread is initialized as a multithreaded apartment (MTA).

大量相互矛盾的信息。

这就是为什么我们将使用 Stackoverflow 上的人所说的作为真正的答案。

最佳答案

此处的信息实际上并不冲突 - 如果您是 COM 新手,则不一定非常清楚。

简短回答:

  • .Net 线程始终已为您 CoInitialized - 您不必(也不应该!)自己调用它。
  • ThreadPool 线程(以及因此使用 ThreadPool 线程的任何内容,如异步委托(delegate)等)始终由 MTA 初始化。创建 STA 线程的唯一选项是添加 [STAThread] Main() 的属性来请求运行时将主线程初始化为 STA,或使用 thread.SetApartmentState(ApartmentState.STA)在调用 thread.Start() 之前创建的新线程上 - 否则默认情况下它们是 MTA。无论如何,一旦线程启动并运行,线程单元模型就无法修改。

更长的答案:有两种方法可以调用 CoInitialize - 您可以使用它来将线程初始化为单线程单元线程 (STA) 或多线程单元线程 (MTA)。上面的文字所说的是,默认情况下,新线程和线程池线程会自动预 CoInitialized 作为 MTA 风格。但是对于新线程,如果您在实际启动线程之前这样做,则可以使用 ApartmentState 来指定 STA 风格。无论如何,在它启动时,它总是以一种方式或另一种方式 CoInitialized。

请注意,基于 UI 的程序上的 Main() 标记有 [STAThread] 属性,以确保它是基于 STA 的;而在控制台应用程序上,缺少 [STAThread] 意味着它是作为 MTA CoInited 的。顺便说一句,此属性的原因是调用 Main() 的线程是您无法使用 ApartmentState 指定 STA 与 MTA 的线程 - 因为它已经在运行并且在 Main() 执行时,所以为时已晚使用它;因此,可以将该属性视为运行时在调用 Main() 之前设置单元状态的提示。

要注意的关键是 STA 通常与 UI 一起使用,并且需要消息循环(.Net WinForms 为您提供了消息循环); STA 代码不应该被 Sleep() 或类似的函数阻塞,否则你的 UI 也会阻塞。另一方面,MTA 是为工作人员使用而设计的 - 例如,后台任务、下载文件或在后台进行计算,并且通常不应该拥有 UI。您可以从其中任何一个使用 COM,但这可能取决于 COM 对象正在做什么或您从哪里获取它。如果它是一个 UI 组件,您可能希望从 STA 线程使用它;另一方面,如果它是用于下载或执行计算的组件,您通常会从 MTA 线程使用它。

上面的更新 1 基本上是说 .Net 运行时总是为您调用 CoInitialize - 但让您选择 STA 与 MTA,其中 MTA 是默认值。

上面的更新 2 基本上是说,由于 ThreadPool 线程是 MTA(并且您无法更改它),因此您应该只将它们用于执行后台操作,而不是将它们用于 UI 任务。

更新 3 表示,对于新线程,您可以选择 MTA 与 STA - 与更新 1 相同,只是对 API 更加明确。

整个 MTA 与 STA 的事情可能会变得相当复杂,建议阅读 this article作为起点。不过,总体情况主要是通过记住 STA = 单线程和 UI 来概括的; MTA = 多线程、后台/辅助任务。 (STA 与 MTA 也适用于对象,而不仅仅是线程,COM 在幕后做了一大堆工作,让不同类型的线程使用不同类型的对象。当它工作良好时,你不会意识到它并且可以幸福地忽略它;但是当您遇到限制或限制时,通常很难弄清楚到底发生了什么。)

关于.net - 在 .NET 中与 COM 交互之前是否需要调用 CoInitialize?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8901869/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com