加载时调用COM对象时,COM +挂起

我们有一些用大家最喜欢的语言(?)-VB6编写的COM +代码。该COM +组件调用由第3方编写的标准COM组件,该组件执行对SQL Server数据库的调用。我们没有在COM +中做任何花哨的事情-仅不过是一个例子(这只是一个示例;我们实际上并未将我们的函数称为doStuff :-)):
Function doStuff
   Dim o As Library.Object
   Set o = New Library.Object
   str = o.DoSomething()
   Set o = Nothing
   doStuff = str
End Function
作为一个非常快速的压力测试,我们将调用包装在一个简单的VBScript中,该VBScript简单地创建对象,循环调用方法,将对象设置为空,然后重复几次。然后,我们在命令提示符下同时运行其中的四个。 我们体验到的是四个COM +窗口停止死亡,好像它们以某种方式相互阻塞一样。根据输出的行为,看起来不同的窗口在沿途某个位置共享对象的实例:例如,窗口之间输出出现的速度在窗口之间同步...因此,两个可以以一定的速度起泡,而其他两个人每秒吐出一条线(当他们吐出线时,它们同时这样做)。 最终,所有四个窗口似乎都停了下来-在组件服务中,我们看到了“呼叫时间”开始攀升(因此,从每个呼叫的几毫秒开始,它攀升至30、40秒)。有时dllhost.exe失败,并且出现COM代理错误对话框(此时,随着生成新的dllhost,窗口将恢复)。 数据库上没有任何活动,因此我们已经排除了一切在数据库层阻塞的情况。通过将COM +组件设置为\“事务:已禁用\”,我们似乎取得了更好的结果,但是挂起不会消失。我们将尝试使用
CreateObject
而不是
new
创建COM对象,以查看其作用(如果有的话)。一旦在COM +和VBScript层完成操作,对象就被设置为Nothing。 值得注意的是,如果直接从VBScript(绕过COM +)调用第三方库,则不会发生任何问题。因此,这似乎与COM +与COM对象进行交互的方式有关,但是除了在Component Services中的对象属性下摆弄不同的设置之外,不确定是否还会发生其他事情。 关于引擎盖下发生什么的任何建议?还是要调整的设置? 额外信息 在回答问题中的答案: 未使用全局变量(根据http://support.microsoft.com/kb/815053) 正确设置了无人参与执行和保留在内存中(按照http://support.microsoft.com/kb/264957) 由于对象是VB COM +对象,因此它正在运行STA,因此无法配置对象池 进一步的工作... 看起来这是COM +或COM中某个地方的同步问题。在我们的测试脚本中,如果在每次迭代中添加10-50ms的随机延迟,问题就会消失。如果我们有固定的延迟,我们将锁定。进行一些谷歌搜索似乎表明,在带有STA的重载COM +上,这可能是个问题,有关此问题,请参见MS博客。返回到Server 2000或Server 2003 SP1的对话框非常好:接下来可能要看一下...     
已邀请:
        听起来您可能在公寓电话外遇到COM +和STA的问题。 微软曾经有一篇很棒的文章,由Michael McKeown发表,题为“从MTS移植到COM +时保持应用程序性能”,对此进行了讨论,但是看起来它已被删除(这里有一个归档版本)。 基本上,COM + STA线程池最多将5个活动绑定到每个STA线程。当您进行非公寓呼叫(第三方组件或SQL Server)时,COM +允许将其他请求作为STA线程上的另一个活动进行服务。最多可以进行5个活动(每个线程)。同样,一旦将控制权交给另一个活动,则在第二个活动完成之前,原始活动无法重新获得控制权。在高负载下和/或如果调用是“长时间运行”,则第一个活动完成的时间是所有其他活动(在线程上)完成的时间的总和。这会影响您的表现。 如果您能够为整个COM +服务器切换设置,则可以将COM +配置为使用旧的MTS 100 STA线程方法。有关详细信息,请参见用于优化COM +线程和活动的注册表项。您可以查看是否对您的表现有所帮助。另一种方法是避免STA组件。     
也许COM +对象池概念和相关文章(如配置要池的组件)会有所帮助。   可池化对象必须满足某些要求才能使多个客户端使用单个对象实例。例如,它们不能保持客户端状态或具有任何线程相似性。     
        我想到两件事: 您是否尝试过将
o
变量设为局部而不是模块级别? 函数doStuff    昏暗为Library.Object    设置o = New Library.Object    str = o.DoSomething()    设置o =否    doStuff = str 结束功能 您是不是Library.Object组件和.DoSomething方法不包含全局变量(或MessageBox语句)? 您可以在每行之后抛出日志记录语句以查看代码在哪里阻塞吗? 点击ProcMon,以查看何时停止点击注册表。最后通话失败了吗?如果是这样,去哪里?     

要回复问题请先登录注册