ActiveX DLL锁定主UI线程

时间:2017-11-13 12:09:14

标签: c# multithreading dll vb6 activex

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

因为VB6 DLL项目包含许多对称为Sheridan Controls(threed32.ocx)的旧库的引用,我已经帮助通知了它并不支持多线程模式" ,在VB6中编译DLL时,我必须将Threading Model选项设置为Single Threaded(而不是Apartment Threaded)。因此,即使我在调用DLL的C#Thread对象上将ApartmentState属性设置为STA,它仍然会阻塞UI线程。

我现在还不确定我的选择是什么。从DLL重构Sheridan控件将是一项繁琐的工作。另一个是接受失败,让DLL在DLL工作时挂起。

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

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

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

1 个答案:

答案 0 :(得分:4)

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

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