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



我想创建一个调用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组件中添加一些DoEvents?
有更好的方法来实现这一点吗?

我不是这方面的专家,但以下是我们如何同时运行嵌入.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>部分

再说一次,我不是这方面的专家,我对这里的一切都不完全了解,但这就是我们如何使它发挥作用的。

如果你有VB6组件的源代码,我建议你用C#重写它——你会从中得到更多(64位执行、线程、更好的基元等)VB6是一种非常古老、不可维护的技术,有很多限制。即使使用VB6,您尝试做的事情也是可能的,但非常很复杂,很难正确。(比在C#中做同样的事情要困难得多。)

如果COM组件是第三方的,并且您无法升级(意味着您必须使用这个旧组件),您可以将COM组件(我认为它是DLL)封装在进程外的COM服务器(VB6中的ActiveX EXE项目)中。

我现在还没有安装VB6,但如果我没记错的话,你可以将新服务器设置为SingleUse,这样每个请求都会启动一个新实例。这将使用VB6提供适当的并行处理,代价是在单独的进程中处理每个调用。(每个过程的寿命约为10秒,由于额外的过程启动成本,可能会更长。)根据旧组件的复杂程度,这可能需要做很多工作。

如果可以的话,只需将旧的VB6组件转换为C#即可——即使这需要更多的工作,至少你不必再处理它了,而且以后更容易维护它。

最新更新