关联IComMethodEvents

时间:2013-03-14 06:50:24

标签: c# c++ delphi monitoring com+

实施IComMethodEvents时,您会收到三个事件。

  1. OnMethodCall
  2. OnMethodException
  3. OnMethodReturn
  4. 我要做的目标是在COM +组件中记录每个方法的调用时间。

    可以使用COMSVCSEVENTINFO结构中的lTimelMicroTime来检索事件的时间,以便在OnMethodCall和{{1}中记录该时间我应该能够计算通话时间,但我怎么能确定这两个事件是相关的。

    通过测试看起来我应该能够使用实时(JIT)激活的对象OnMethodReturn

    这样做有什么问题或有其他方法吗?

    可能存在的一个问题是,我发现oid经常被重用,所以如果由于某种原因导致的事件无序发生,那么实现相关可能会有点困难。

    更新1:

    进一步测试表明,oid在多用户场景中是不够的。同时使用相同的对象,因此必须至少使用oidoid进行相关。后续问题将是:如何从COM +事件订阅者获取原始调用者?

    更新2:

    刚刚找到IComMethod2Events。区别在于事件具有执行调用的线程的标识符。在测试中看起来很有前途,我无法想象相关性可能会失败的情况。 COM +组件的线程模型为original caller

    更新3

    在本文中,使用了Creating COM+ PerfMon Counters to Monitor COM+ Data Any Apartment。我不认为这在多线程公寓中已经足够了。

    <子> 注意:我最终会在Delphi中实现它,所以我添加了Delphi标记。我还添加了C#标签,因为用于实现接口的语言可能根本不重要。 更新:暂时添加c ++标签只是为了引起之前实际使用过这些内容的人的注意。

2 个答案:

答案 0 :(得分:3)

  

...如果由于某种原因导致的事件无序发生......

他们永远不会这样做。 COM +系统事件发布者使用COM + Events服务触发这些事件。从事件发布者的角度来看,事件的调用是同步的。当发布者触发事件时,在所有订阅者完成已触发事件的处理之前,它不会继续执行下一个事件。很自然地,OnMethodReturn/OnMethodException事件在匹配OnMethodCall之前不会发布。我记得在COM +事件中阅读有关竞争条件/破坏订阅的知识库。据我所知,所有这些错误都已在Windows 2000的各种Service Pack中得到解决。但诚然,我并不想在这个领域保持最新状态。

实施IComMethod2Events时,您订阅与IComMethodEvents完全相同的临时订阅。所以被解雇事件的顺序也是一样的。

  

...因此必须至少使用oidoriginal caller ...

进行相关

此时我真的不确定您是否正确解释了测试结果。你是如何测试的?

oid应该已经封装了所需的所有信息,即使在具有JIT和池的“多客户端”场景中也是如此。上次我实现了这样的事件监听器(已经有一段时间了),依靠oid计算得很好。虽然,我环境中的大多数组件都是用VB6编写的(因此,它们都存在于STA中)。然而,即使使用STA,您也可以通过单个线程在不同的执行阶段进行多次调用。由于COM + STA线程池中存在线程数的上限,因此可能出现以下情况:调用A在特定线程上启动,调用B在同一线程上启动,调用B返回,调用A返回。我不记得在没有“关于来电者的其他信息”的情况下跟踪oid的来电有任何问题。

您考虑的实施理念大体上是规范的。 Platform SDKs附带的COM+ spy示例使用oid参数来跟踪单个调用。您可以在<Path to SDK samples>\Samples\com\administration\spy中找到该应用程序的来源。该示例已经使用了这个实现很长一段时间(至少从Windows 2003开始)。今天它是MTA甚至COM +介绍之后的永恒。如果存在缺陷,此时将更新样本。希望。

答案 1 :(得分:1)

MSDN链接“Creating COM+ PerfMon Counters to Monitor COM+ Data”似乎与您的目标非常相似(尽管我认为在托管C ++中)。

相关部分就是这个,我想:

void IComMethodEvents.OnMethodCall(ref COMSVCSEVENTINFO ei, ulong
    lObjID, ref Guid gClsID, ref Guid gIID, uint nIndex)
{
    //Make sure that monitoring is enabled and that our performance
    //counter has been initialized.
    if (Monitor && pcMethodDuration != null)
    {
    try
    {                    
        //We are going to store the initial value in a Sorted List 
        //collection. To do this we are going to need a key that
        //represents this call.
        string strKey = lObjID.ToString() + gClsID.ToString() + 
            gIID.ToString() + nIndex.ToString();

这可能是您对oid(在他们的示例中为lObjID)的思考的解决方案。 不知道这是否涵盖了您的多用户场景,您将不得不尝试一下。该页面有很多关于这个主题的细节,所以希望你能够弄明白。祝你好运。