代码之家  ›  专栏  ›  技术社区  ›  Sunny Milenov

运行时可调用包装器(RCW)作用域-进程还是应用程序域?

  •  6
  • Sunny Milenov  · 技术社区  · 17 年前

    运行时只创建一个RCW 对于每个COM对象,无论 上存在的引用数 那个物体。

    我的应用程序在它自己的应用程序域中运行(它是Outlook加载项),我想知道如果在循环中使用Marshal.ReleaseComObject(x),直到它的计数达到0(推荐值),会发生什么情况。它是否会释放来自其他加载项(在同一Outlook进程的其他应用程序域中运行)的引用?

    编辑:完美-现在混乱更大了。根据两个答案(来自Lette和Ilya),我们有两个不同的答案。官员 MSDN doc ver. 1.1 of the doc

    同时,在Mason Bendixen的文章中,它说它是每个appdomain的。

    由于他的文章是旧的(2007年4月),我给他发了一封电子邮件,要求澄清,但如果其他人必须添加一些内容,请添加。

    谢谢

    3 回复  |  直到 15 年前
        1
  •  3
  •   Ilya Ryzhenkov    17 年前

    在managed中,我们有一个每个应用程序域 RCWs。当IUnknown进入 通过激活,作为回报 方法调用中的参数等), 我们检查缓存以查看是否存在RCW COM对象已存在。如果 返回现有的RCW。否则

    从…起 Mason's Blog

        2
  •  3
  •   Aidan Ryan    17 年前

    Ilya引用的Mason Bendixen博客文章是正确的:RCW的作用域是AppDomain,而不是流程。我只能猜测 Runtime Callable Wrapper (MSDN 2.0) 这篇文章是“随便”说的。这篇文章在一般意义上并不一定是错误的,因为它最典型的执行方式是只使用一个AppDomain,但这句话在技术上并不准确。

    关于你的具体问题:

    “我想知道如果我 使用封送处理中的Marshal.ReleaseComObject(x) 推荐)。它会释放吗 其他加载项的引用 (在其他应用程序域中运行) 在同一Outlook流程中)?”

    这个问题的答案取决于如何设置外接程序。通常,如果您不采取预防措施,那么答案是肯定的,这将影响从同一AppDomain中运行的其他加载项中的引用。但是,由于您声明您是从一个单独的AppDomain运行的,那么,不,它不会。

    COM Shim Wizard Version 2.3.1 可用于隔离外接程序的。COM垫片向导的文档可在以下位置找到: Isolating Microsoft Office Extensions with the COM Shim Wizard Version 2.3.1 .

    (1) 通过使用单独的自定义COM入口点,您的外接程序将由Microsoft Office与所有其他外接程序分别正确标识。否则,默认情况下,所有加载项共享相同的默认mscoree.dll加载程序。共享同一加载程序的问题在于,如果任何加载项发生崩溃,则Microsoft Office会将mscoree.dll识别为问题的根源,并且下次不会自动加载它。您可以再次手动打开,但由于其他加载项中存在问题,您的加载项下次将不会自动加载!

    使用COM垫片向导的缺点是,在单独的AppDomain之外操作会产生额外的编组开销。我不认为这对于Microsoft Outlook加载项来说是显而易见的。但是,对于一些对对象模型有大量调用的密集例程来说,这可能是一个因素,例如Microsoft Excel加载项有时就是这样。

    您声明已经在从单独的AppDomain运行外接程序。如果这是真的,那么您已经与其他AppDomain的Marshal.ReleaseComObject(对象)和Marshal.FinalReleaseComObject(对象)调用隔离。(顺便问一下,我很好奇您是如何做到这一点的……您是否明确地创建了自己的AppDomain?Visual Studio中的默认外接程序模板会这样做 在单独的AppDomain中运行,并使用mscoree.dll加载。)

    如果您正在创建自己的AppDomain,您的代码是隔离的,但是它的标识可能不会与其他外接程序分离,因为您的外接程序仍将共享默认的mscoree.dll加载程序,除非您使用其他方法来解决此问题。

        3
  •  1
  •   Community Mohan Dere    8 年前

    根据同样的文件:

    每道工序 对于每个对象。

    我想我们可以有把握地假设 对象 例子 ,因此,如果addins/AppDomains不包含对同一实例的引用,则调用 ReleaseComObject 不会释放对在其他位置创建的实例的引用。

    编辑:单据的措辞可能有误, as stated elsewhere 释放对象