- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我知道每个线程调用 COM 的要求 CoInitialize
在与 COM 系统交互之前。
.NET 公开了一些在线程上内部操作的项目,例如:
ThreadPool
线程BackgroundWorker
类(使用异步委托(delegate)(使用线程池线程))如果我要从线程与 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 新手,则不一定非常清楚。
简短回答:
[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/
我正在寻找一种使此打印 HTML 代码 fragment 向后兼容旧 Android 版本的简单方法: @TargetApi(Build.VERSION_CODES.KITKAT) private v
我在 GCC 终端 (centos linux) 中为 ATM 项目编译以下 c 和 .h 代码时收到以下错误。请帮忙,因为我是编程新手。 validate_acc.h #ifndef _VALIDA
在写关于 SO 的不同问题的答案时,我制作了这个片段: @import url('https://fonts.googleapis.com/css?family=Shadows+Into+Light'
试图弄清楚我应该如何在 my_div_class 之前放置一个 span 而不是替换所有它。现在它取代了 div,但我不想这样做。我假设它类似于 :before 但不知道如何使用它。 { va
我正在使用选择库 http://github.hubspot.com/select/和 noUiSlider https://refreshless.com/nouislider/ .我面临的问题如下
我是开发新手,独自工作。我正在使用 Xcode 和 git 版本控制。可能我没有适本地组织和做错事,但我通常决定做 promise 只是为了在我破坏一切之前做出安全点。在那一刻,我发现很难恰本地描述我
我想确保在同一个桶和键上读取和写入时,应该更新获取的值,也就是说,应该在对其进行写入操作之后获取它。我怎样才能做到这一点? 我想要的是,如果我更新一个键的值,如果我同时使用不同线程获取值,则更新同一个
我的问题与this有关问题,已经有了答案: yes, there is a happens-before relationship imposed between actionsof the thre
The before and after hook documentation on Relish仅显示 before(:suite) 在 before(:all) 之前调用。 我什么时候应该使用其中
我有 CSV 行,我想在其中检测所有内部双引号,没有文本限定符。这几乎可以正常工作,但我的正则表达式还可以检测双引号后的字符。 CSV 部分: "7580";"Lorem ipsum";"";"Lor
是否可以通过Youtube数据API检查广告是否可以与特定视频一起显示? 我了解contentDetails.licensedContent仅显示视频是否已上传至同一伙伴然后由其声明版权。由于第三者权
考虑一下用漂亮的彩色图表描述的“像素管道” https://developers.google.com/web/fundamentals/performance/rendering/ 我有一个元素(比
之前?
在 MVC3 中,我可以轻松地将 jQuery 脚本标签移动到页面底部“_Layout.vbhtml” 但是,在 ASP.NET MVC3 中,当您使用编辑器模板创建 Controller 时,脚手
悬停时内容被替换,但是当鼠标离开元素时我希望它变回来。我该怎么做? $('.img-wrap').hover(function(){ $(this).find('h4').text('Go
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 已关闭 9 年前。 有关您编写的代码问题的问题必须在问题本身中描述具体问题 - 并包含有效代码以重现该问题。
版本:qwt 6.0.1我尝试开发频谱的对数缩放。我使用简单的线条来启用缩放plotspectrum->setAxisScaleEngine(QwtPlot::yLeft, new QwtLog10S
我有两个相同的表,I_Subject 和 I_Temp_Subject,我想将 Temp_Subject 表复制到 Subject 表。 I_Temp_Subject 由简单用户使用,I_Subjec
我的印象是第一次绘制发生在触发 DOMContentLoaded 事件之后。特别是,因为我认为为了让第一次绘制发生,需要渲染树,它依赖于 DOM 构造。另外,我知道 DOM 构造完成时会触发 DOMC
我是一名优秀的程序员,十分优秀!