【问题标题】:ActiveX DLL locks up main UI threadActiveX DLL 锁定主 UI 线程
【发布时间】:2017-11-13 12:09:14
【问题描述】:

我正在努力在 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 DLL?它是您尝试嵌入到 GUI 中的控件吗?
  • 如果你没有返回值,或者简单类型的返回值,你可以在命令行 exe 中包装 ActiveX,然后用 CreateProcess set usynchroniuos = yes 'Shell'你的 exe..跨度>
  • 这与 .NET 控件的行为方式没有根本不同。除了如果您从工作线程分配它们的属性,那么您就有希望获得 InvalidOperationException 并学习使用 Control.BeginInvoke()。对于 ActiveX 控件,这完全是自动的。这些控件是 20 年前为比您现在使用的机器慢约 65 倍的机器制作的。所以它们本质上不会“堵塞”任何东西。除非你犯了用数千件东西塞满它们的传统错误。
  • 在 Visual Studio 中启动一个命令行项目,引用你的 ActiveX DLL,运行函数然后返回值作为处理结果
  • 执行此操作的“正确”方式过去是创建一个“进程外”组件并编组数据,但如果您需要的只是其中的一个 double 值,则包装dll 并按照建议使用 CreateProcess 运行就足够了。

标签: c# multithreading dll vb6 activex


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-29
    • 1970-01-01
    • 2012-01-23
    • 1970-01-01
    • 1970-01-01
    • 2014-08-21
    相关资源
    最近更新 更多