我正在使用一个 COM 接口(interface),根据注册表中 CLSID 条目中的 ThreadingModel =“Free”,该接口(interface)支持多线程单元。多线程似乎是在非常基础的级别上实现的,但是,方法调用通常会返回“类正忙”状态代码。
在 CoInitializeEx 中切换到 STA 并使用接口(interface)编码(marshal)处理让 COM 系统序列化请求并避免这种行为(我只从主线程进行调用时从未遇到过这种情况)是否存在任何风险?
谢谢!
最佳答案
使用 STA 线程来承载 COM 对象不会产生任何影响。 COM 关注注册表中的 ThreadingModel 值。由于它是“自由”的,因此它不会认为需要编码(marshal)接口(interface)指针,并且仍然会从工作线程进行调用。
您必须修改注册表项并将其更改为“两者”。
这不是一个很好的解决方案,它很快就会崩溃。自己处理这个问题要好得多。使用 Control.Begin/Invoke() 或 Dispatcher.Begin/Invoke(),具体取决于您用于实现所需消息循环的类库。请注意,您现在还有一个选择,COM 编码(marshal)处理相当于 Invoke(),但您可以(可能)使用 BeginInvoke() 进行优化。
最后但并非最不重要的一点是,复制 COM 服务器中存在的产生“忙”错误代码的锁定是一种可能的解决方案。您通过在每次调用之前获取自己的锁来解决这个问题的可能性非零,从而自己序列化调用。您的工作线程现在将阻塞,而不必处理错误代码。联系组件的作者是明智的,他可以轻松地告诉您应该序列化哪些特定方法。
关于multithreading - COM接口(interface): Using STA instead of MTA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24572585/