COM+;在加载下调用COM对象时挂起

COM+;在加载下调用COM对象时挂起,com,vb6,com+,Com,Vb6,Com+,我们有一些COM+代码是用大家最喜欢的语言(?--VB6)编写的。此COM+组件调用由第三方编写的标准COM组件,该第三方执行对SQL Server数据库的调用。我们在COM+中不做任何花哨的事情——只不过(这只是一个示例;我们不真正调用函数doStuff:-): 作为一个非常快速的压力测试,我们将调用封装在一个简单的VBScript中,该脚本简单地创建对象,在循环中调用方法,将对象设置为nothing,并重复几次。然后在命令提示符下同时运行其中四个 我们所体验到的是,四个COM+窗口停止运行,

我们有一些COM+代码是用大家最喜欢的语言(?--VB6)编写的。此COM+组件调用由第三方编写的标准COM组件,该第三方执行对SQL Server数据库的调用。我们在COM+中不做任何花哨的事情——只不过(这只是一个示例;我们不真正调用函数doStuff:-):

作为一个非常快速的压力测试,我们将调用封装在一个简单的VBScript中,该脚本简单地创建对象,在循环中调用方法,将对象设置为nothing,并重复几次。然后在命令提示符下同时运行其中四个

我们所体验到的是,四个COM+窗口停止运行,好像它们以某种方式相互阻塞。根据输出的行为,看起来不同的窗口在某个地方共享对象的实例:例如,输出在窗口之间出现的速度在窗口之间同步。。。因此,两个可以高速起泡,而另外两个每秒吐出一条线(当他们吐出线时,他们同时吐出)

最后,所有四个窗口似乎都停止了——在组件服务中,我们看到调用时间开始上升(因此从每次调用的几毫秒上升到30到40秒)。有时dllhost.exe失败,会出现一个COM代理错误对话框(此时窗口会恢复为生成新的dllhost)

数据库上没有任何活动,因此我们排除了在数据库层发生阻塞的可能性。通过将COM+组件设置为“Transactions:disabled”,我们似乎取得了更好的效果,但挂起并没有消失。我们将尝试使用
CreateObject
创建COM对象,而不是
new
,以查看它的作用(如果有的话)。在COM+和VBScript层中完成后,对象将设置为“无”

值得注意的是,如果直接从VBScript调用第三方库(绕过COM+),则不会出现任何问题。因此,这似乎与COM+与COM对象交互的方式有关,但除了在组件服务的对象属性下处理不同的设置外,并不确定还会发生什么

有没有关于引擎盖下发生了什么导致这种情况的建议?还是要调整设置

额外信息
在回答回答中的问题时:

  • 未使用全局变量(根据)
  • 无人值守执行和内存保留设置正确(根据)
  • 由于对象是VB COM+对象,它正在运行STA,因此无法配置对象池
进一步的工作… 它看起来像是COM+或COM中某个深层次的同步问题。在我们的测试脚本中,如果我们在每次迭代中添加10-50ms的随机延迟,问题就会消失。如果我们有固定的延迟,我们就锁定。一些谷歌搜索似乎表明,在带有STA的重载COM+上可能会出现问题,而STA是。回到Server2000或Server2003SP1框会很好:这可能是下一步要看到的东西……

也许像这样的相关文章会有所帮助

可池对象必须满足某些要求,才能使单个对象实例供多个客户端使用。例如,它们不能保持客户端状态或具有任何线程关联

我想到两件事:

  • 您是否尝试过将
    o
    变量设置为本地变量而不是模块级别

    函数doStuff Dim o作为库对象。对象
    Set o=New Library.Object str=o.剂量测定法() 设置o=无 doStuff=str 端函数

  • 您是否认为Library.Object组件和.DoSomething方法不包含全局变量(或MessageBox语句)

  • 您能在每行之后抛出日志语句来查看代码阻塞的位置吗

  • 点击查看它何时停止访问注册表。上次通话失败了吗?如果是,去哪里


  • 听起来您可能遇到了COM+和STA公寓外通话的问题

    微软曾经有一篇由Michael McKeown发表的名为“从MTS移植到COM+时保持应用程序性能”的伟大文章讨论过这一点,但看起来它已经被删除(有一个存档版本)

    基本上,COM+STA线程池将最多5个活动绑定到每个STA线程。当您拨打公寓外呼叫(第三方组件或SQL Server)时,COM+允许将其他请求作为STA线程上的另一个活动提供服务。这最多可以发生在5个活动中(每个线程)。此外,一旦将控制权授予另一个活动,则在第二个活动完成之前,原始活动无法重新获得控制权。在重载和/或调用“长时间运行”的情况下,第一个活动完成的时间是所有其他活动(线程上)完成的时间之和。这会扼杀你的表现


    如果您能够切换整个COM+服务器的设置,则可以将COM+配置为使用旧的MTS 100 STA线程方法。有关详细信息,请参阅。你可以看看这是否有助于你的表现。另一种方法是避免STA组件。

    由于这是一个VB6 COM+对象,无法设置池选项,因为VB6 COM+对象仅为STA。第三方组件没有在COM+中注册——它是一个标准的COM组件。没错。这可能与VB6代码中全局变量的使用有关吗?没有,检查过了。我们还仔细检查了无人参与执行标志和保留在内存中的标志是否按照1正确设置。确实存在,只是缺少[现在修复];2.没有MessageBox-DLL不是为直接与UI交互而设计的-globals不知道;3. & 4.我们可能需要做些什么:我怀疑这是对第三方lib的调用。。。作为
    Function doStuff
       Dim o As Library.Object
       Set o = New Library.Object
       str = o.DoSomething()
       Set o = Nothing
       doStuff = str
    End Function