问题标签 [apartments]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 单线程单元模型 - 如何处理创建工作线程的 COM 对象?
我有一个在 STA EXE(调用CoInitialize(NULL)
)中实现的 COM 对象,我们称它为CMyObject
实现IControl
. 伪代码是这样的:
我的测试代码基本上遵循这种模式并且没有问题(到目前为止)但阅读STA 上的 MSDN表明我需要:
- 呼入
CoInitialize
/CoUninitialze
入ThreadMain
- 使用编组从工作线程调用接口
这个问题(如何从不同的公寓模型访问 COM 对象?)也表明需要编组并提倡使用 GIT。
然而,公寓模型是 COM 的一部分,我从来没有真正理解过,我想检查一下这在我的情况下是否必要 - 特别是因为它目前运行良好而没有抛出错误 - 我不想添加代码只是“万一需要,我不能说”。
如果有任何区别,那么ISomething
有问题的 COM 对象仅由工作线程调用,而不是由主线程调用。在我的具体情况下,CMyObject
任何时候都只会存在一个。
c# - 如何为使用 AppDomain.ExecuteAssembly 加载的代码设置 COM 单元状态?
当我创建一个Thread
时,我可以选择在启动它之前明确设置它的 COM 单元状态。例如:
但是当我创建一个AppDomain
并将一些代码加载到其中时,我似乎对线程的创建没有明确的控制,所以我无法调用SetApartmentState
:
有没有办法指定在 an 内部创建的主/入口线程AppDomain
应该使用特定的 COM 单元状态?
我知道Plugin.dll
' 的主要入口方法可以用[STAThread]
or[MTAThread]
属性标记;但是让我们假设Plugin.dll
没有明确声明或设置 COM 单元状态,并且我无法更改Plugin.dll
.
c++ - 元帅还是不元帅
我找不到以下问题的明确答案:如果一个 COM 类是线程安全的,即它被标记为 Both 或 Free,我真的需要编组它的对象接口以将其传递给同一进程中的另一个线程吗?我不问两个线程是否都属于 MTA 的情况,我问的是每个线程都属于它自己的 STA 的情况。
我知道在属于不同单元的线程之间编组接口的规则,我的问题是如果我将原始接口指针传递给不同单元中的线程并且每个线程调用线程安全的对象上的方法会发生什么?
根据我的经验,它运行良好,我的问题是,如果这是一个时间问题,并且很危险并且可能由于任何原因导致崩溃,还是完全安全并且有规则很好?
multithreading - FreeThreadedDOMDocument、Neutral Apartments 和 FreeThreaded Marshaler
正如 MSDN 所说:
如果您正在编写单线程应用程序(或一次只有一个线程访问 DOM 的多线程应用程序),请使用租用线程模型(Msxml2.DOMDocument.3.0 或 Msxml2.DOMDocument.6.0)。如果您正在编写一个应用程序,其中多个线程访问将同时访问一个 DOM,请使用自由线程模型(Msxml2.FreeThreadedDOMDocument.3.0 或 Msxml2.FreeThreadedDOMDocument.6.0)。
FreeThreadedDOMDocument、中性公寓和自由线程编组器之间有什么联系吗?我查看了 OleView,发现 FreeThreadedDOMDocument 线程模型是 Both。据我了解,自由线程封送器支持中性公寓对象。这是否意味着 FreeThreadedDOMDocument 不使用自由线程编组器,并且它被称为自由线程有点令人困惑?
标记为 Free、Both 或 Neutral 的 COM 类之间的实现区别是什么?据我了解,它们都必须是线程安全的,为什么有区别?Neutral 应该支持自由线程编组器是否正确?
c# - 在 C# 中跨线程单元时出现错误“无法转换类型的 COM 对象”
我一直在使用第三方 SDK 作为 C# 中的引用 dll,在 Windows 10 上使用 .NET 4.5.2。IDE 围绕 dll 创建了一个互操作,我可以看到适当的命名空间、接口、枚举等。我正在使用的 SDK 适用于 Blackmagic ATEM Television Studio,但我认为这没有直接关系。
SDK 提供了一个对象,我可以使用它来定位/发现附加的硬件并返回一个对象的实例,它似乎是底层 COM 对象的包装器 (RCW)。
发现代码如下所示:
如果我在作为 STA 单元的 WPF UI 线程上执行此代码,它将毫无问题地工作。我能够毫无错误地使用该对象。但是,如果我尝试从任何新线程(STA 或 MTA)访问生成的切换器对象,我将收到类似于以下内容的错误:
无法将类型为“System.__ComObject”的 COM 对象转换为接口类型“BMDSwitcherAPI.IBMDSwitcherMixEffectBlock”。此操作失败,因为 IID 为“{11974D55-45E0-49D8-AE06-EEF4D5F81DF6}”的接口的 COM 组件上的 QueryInterface 调用因以下错误而失败:不支持此类接口(来自 HRESULT 的异常:0x80004002 (E_NOINTERFACE)) .
引用 MikeJ 和他对类似问题的回答:
这个讨厌的、讨厌的异常是由一个称为 COM 编组的概念引起的。问题的本质在于,为了从任何线程消费 COM 对象,线程必须能够访问描述 COM 对象的类型信息。
在这一点上,我决定稍微调整我的策略并尝试从 MTA 线程中调用发现逻辑。像这样:
这似乎有效,但需要付出代价。
权衡是我现在可以从任何后台 (MTA) 线程毫无问题地使用我的切换器对象,但我的整个应用程序在运行大约 15 分钟后将简单地崩溃。在有人说之前,我知道这不是线程安全的。我认识到在多个 MTA 线程尝试使用我的切换器对象之前需要一些同步逻辑。但那是在路上,现在如果我运行上面的代码并简单地让应用程序空闲 15 分钟,它每次都会崩溃。
因此,一方面我有一个稳定的应用程序,但我只能使用 UI 线程中的库,另一方面我有一个不稳定的应用程序,但我可以使用任何(MTA)后台线程中的库。
由于我的应用程序的性质,最好能够从多个后台线程使用该库。例如,一个线程可能正在生成图形并将其上传到设备,而另一个线程正在管理切换视频输入,第三个线程正在管理音频输入,而 UI 线程正在处理 ID-10T bonk 对话框......所有这些可以从 UI 线程完成,但如果可能的话,我真的宁愿避免这种情况。
所以:有什么方法可以在 UI(STA)线程上发现并创建我的切换器对象(理论上避免在 15 分钟内爆炸),但让我的后台(MTA)线程可以访问类型信息,这样他们也可以使用切换器?或者,在后台(MTA)线程上发现/创建我的切换器对象是否安全,但我需要做一些事情以某种特殊方式“标记”它以避免 15 分钟的爆炸?
编辑:
在阅读了 Hans Passant 的评论并调查了他提供的链接后,我改编了引用的 STAThread 类以供我自己在 WPF 中使用。但我对 SynchronizationContext 和 Dispatcher 有点模糊。下面列出的代码是否可以安全地用作“围绕”我的 COM 对象的包装器,而不会在任何“长时间运行”操作期间阻塞 UI?我的用例是运行一个 Task() 来准备一些数据,然后调用一些代码与我的 COM 对象进行交互,当操作完成时,代码流在正在运行的 Task 中恢复以执行下一系列操作。 .
powershell - 如何使用可执行脚本块和 ApartmentState 参数在 PowerShell 中设置线程?
如何设置线程并使用一些可执行代码启动它ApartmentState = "STA"
?我只是找到了这种方法,但我不知道如何将我的脚本块传递给它。
我需要在这个线程中获取剪贴板文本,如下所示:
我也试过了Start-Job
。
multithreading - 无法将线程并发模型设置为多线程单元
我创建了一个新的 DUnit 测试项目,并尝试在其开始时设置多线程单元。问题是在一台计算机上更改了公寓类型。
现在,当我运行这个简单的测试时:
我不明白不同计算机上的不同行为。这是由于不同的操作系统造成的吗?在我的测试中,我可以生成另一个线程并为其指定公寓模型,它会起作用,但我好奇的天性想知道为什么在上述情况下会产生不同的结果。
GetCurrentApartmentType
已按照本文中的方式实施,并且可以正常工作。这是一个示例应用程序,用于说明我遇到的一些需要在多线程单元模型中运行的 COM 对象的问题。
ruby-on-rails - 使用 Apartment Gem 切换租户时出错
Apartment::Tenant.switch!("tenant_name")
即使租户存在,我在执行时也会出错。
当我运行 Apartment::tenant_names 时,它返回一个包含数组,["murah5","rahmatullah","test"]
然后我运行Apartment::Tenant.switch!("murah5")
它返回:
Apartment::TenantNotFound: One of the following schema(s) is invalid: "murah5" "public" from /Users/fourtyonestudio/.rvm/gems/ruby-2.4.1/gems/apartment-1.2.0/lib/apartment/adapters/postgresql_adapter.rb:72:in
在 connect_to_new 中救援'`
你能帮我处理这个案子吗?
c# - 无法在 C# 中处理 com 事件
如何在 C# 中处理 com 事件?
我在 c# 中创建了一个类库,并使用无注册表 com 技术作为 com 组件公开。
这是我的客户 Windows 申请表。
当我调用 service.RaiseEvent 时,什么也没有发生。任何帮助,将不胜感激。
com - 在单线程单元模型中,对方法的任何调用是否同步?
我的疑问是,在 STA 中,对同一接口中不同方法的调用是否排队?或在同一接口中对同一方法的调用排队?