C# ActiveX DLL锁定主UI线程

C# ActiveX DLL锁定主UI线程,c#,multithreading,dll,vb6,activex,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中重构She

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

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

我不确定在这一点上我的选择是什么。从DLL中重构Sheridan控件将是一项乏味的工作。另一种方法是接受失败,让UI在DLL工作时挂起

我想我的主要问题是;有人知道我可以(不费吹灰之力)在单独的进程/服务中运行单线程ActiveX DLL的方法吗?该进程/服务可以从主C#线程异步调用?或者还有其他我不知道的选择吗

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


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

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


这就是进程外组件的用途。它们在一个单独的线程中执行——事实上是在一个单独的进程中。缺点是通信需要跨越进程边界,但在您的情况下,这不是一个问题,而且它们相对容易设置:

这是什么类型的ActiveX DLL?它是您试图嵌入到GUI中的控件吗?如果您最多没有返回值或简单类型返回值,您可以将ActiveX包装到命令行exe中,然后使用CreateProcess set usynchroniuos=yes“Shell”exe。这与.NET控件的行为方式没有根本区别。除了如果您从工作线程分配它们的属性,那么您就有希望获得InvalidOperationException并学习使用Control.BeginInvoke()。对于ActiveX控件,这完全是自动控制的。这些控制装置是20年前为比现在使用的机器慢65倍的机器制造的。所以他们不会天生“阻塞”任何东西。除非你犯了传统的错误,用成千上万的项填充它们。在Visual Studio中启动命令行项目,引用ActiveX DLL,运行函数,然后将值作为进程结果返回。执行此操作的“正确”方法过去是创建“进程外”组件并跨,但是,如果您只需要从中提取一个双倍值,那么按照建议包装dll并使用CreateProcess运行就足够了。