在多个线程中从DotNet调用VB6 COM函数

时间:2016-06-03 07:12:36

标签: .net multithreading vb6

我想创建一个调用VB6 COM函数的.net应用程序。 COM组件声明为Multiuse。

Private _App As ComObject = New ComObject

Public Sub Start()
    Dim Thread1 = New Threading.Thread(Sub() DoSomething())
    Dim Thread2 = New Threading.Thread(Sub() DoSomething())
    Dim Thread3 = New Threading.Thread(Sub() DoSomething())
    Thread1.Start()
    Thread2.Start()
    Thread3.Start()
End Sub

Private Sub DoSomething()
    _App.DoSomeComLogic
End Sub

COM组件中的逻辑大约需要10秒钟才能继续。但是Thread3在30秒后完成。

有没有办法多线程这些函数调用?
我是否需要在VB6组件中添加一些DoEvent?
有没有更好的方法来实现这一目标?

2 个答案:

答案 0 :(得分:0)

我不是这方面的专家,但这里是我们如何能够同时运行嵌入到 .NET asmx Web 服务中的 VB6 COM dll。请参阅 https://weblog.west-wind.com/posts/2012/sep/18/creating-sta-com-compatible-aspnet-applications 以获得一篇好文章。

  • 必须在 VB6 项目的属性中将 DLL 设置为单线程单元 (STA)。
  • 运行 .NET 项目的 IIS 池必须设置为经典管道,而非集成。
  • IIS 池必须“启用 32 位应用程序”
  • 您必须创建一个自定义 http 处理程序,以使 .NET 项目在 STA 环境中运行,而不是在默认的 MTA(多线程单元)中运行。有关示例,请参见上面的链接(还有一些其他示例)。显然,对于 aspx 页面来说这非常简单——您只需设置 AspCompat 标志,但是 asmx Web 服务无法做到这一点,而这正是自定义 http 处理程序类的用武之地。
  • 您还需要在 web.config 的 <httphandlers> 部分添加自定义处理程序。
  • 如果您运行的是 .NET 4.5+,您还需要将 <add key="aspnet:UseTaskFriendlySynchronizationContext" value="false" /> 添加到 web.config 的 <appSettings> 部分。

再说一次,我不是这方面的专家,我对这里的所有内容都没有完全了解,但这就是我们能够让它发挥作用的方式。

答案 1 :(得分:-1)

如果您拥有VB6组件的源代码,我建议您只需在C#中重写它 - 您将从中获得更多(64位执行,线程,更好的原语等)。 )VB6是一种非常古老,无需维护的技术,具有许多限制。即使使用VB6,您也可以尝试做什么,但非常非常复杂且难以正确使用。 (比在C#中做同样困难得多。)

如果COM组件是第三方而您无法升级(意味着您必须使用此旧组件),则可以将COM组件(我假设是DLL)包装在进程外COM服务器中( VB6中的ActiveX EXE项目。)

我目前没有安装VB6,但如果我没记错,您可以将新服务器设置为SingleUse,以便为每个请求启动一个新实例。这将使您使用VB6进行适当的并行处理,但代价是在单独的进程中处理每个调用。 (每个过程将持续大约10秒 - 由于额外的过程启动成本,可能会持续一段时间。)根据旧组件的复杂程度,这可能需要做很多工作。

如果可以,只需将旧的VB6组件转换为C#即使它的工作量更大,至少你不再需要处理它,并且更容易维护它。