c# - ActiveX DLL 锁定主 UI 线程

标签 c# multithreading dll vb6 activex

我正在努力在 C# WinForms 应用程序的后台线程中运行来自 ActiveX DLL(从 VB6 编译)的函数。

因为 VB6 DLL 项目包含很多对名为 Sheridan Controls (threed32.ocx) 的旧库的引用,我被告知“不支持多线程模式”,我必须设置线程模型选项在 VB6 中编译 DLL 时改为单线程(而不是单元线程)。因此,即使我在调用 DLL 的 C# Thread 对象上将 ApartmentState 属性设置为 STA,它仍然会阻塞 UI 线程。

我不确定此时我的选择是什么。从 DLL 重构 Sheridan 控件将是一项乏味的工作。另一种是认输,让 UI 挂起,而 DLL 继续工作。

我想我的主要问题是;有谁知道我可以(没有太多麻烦)在可以从主 C# 线程异步调用的单独进程/服务中运行单线程 ActiveX DLL 的方法吗?或者还有其他我不知道的选项吗?

已解决:根据用户@mnistic 提供的信息,我找到了解决方案。我必须将 ActiveX DLL 重建为 ActiveX EXE,它作为进程外组件运行。为了让它工作,我必须在项目属性中将“启动模式”设置为“独立”。我还将 VB6 类上的 Instancing 参数设置为 SingleUse,以确保全局状态不会跨实例共享。

更新项目引用后,我能够从我的 C# 应用程序的后台线程中调用库中的函数,而不会导致 GUI 滞后。

最佳答案

在谈到 ActiveX 时,Microsoft 区分了进程内组件和进程外组件。有时,当人们谈论 ActiveX 时,他们指的是进程内组件、dll 或 ocx 文件,这些文件与使用它们的客户端在同一进程中运行。通常,这些组件包括 GUI 元素,VB6 使这些元素易于嵌入到客户端应用程序中。但是,进程内组件必须使用客户端的执行线程,在您的情况下,这会导致主线程中的感知锁定。

这就是进程外组件的用途。它们在单独的线程中执行——事实上是单独的进程。缺点是通信需要跨越进程边界,但在您的情况下这不是问题,而且它们相对容易设置:https://msdn.microsoft.com/en-us/library/aa262334%28v=vs.60%29.aspx

关于c# - ActiveX DLL 锁定主 UI 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47264054/

相关文章:

c# - 你必须刷新你的 BinaryWriter 数据吗

c# - 如何从元素中具有相同名称的 xml 文件中获取特定值?

python - 可停止线程错误

javascript - 将 JavaScript 回调传递给在另一个线程中调用它的 FFI 函数是否安全?

c++ - 删除在 DLL 中创建的对象

c# - 为什么 Autofac 不调用我的类' `Dispose()` ?

c# - 如何确定 Linq-To-Sql 对象中更改了哪些字段

java - 多线程多锁似乎比单锁慢

c - 允许在VB.net代码中调用C dll

c# - DLL中的单例被销毁