C# 如何将Marshal.ReleaseComObject与Win32本机函数一起使用

C# 如何将Marshal.ReleaseComObject与Win32本机函数一起使用,c#,.net,com,interop,C#,.net,Com,Interop,我正在使用这两个本机win32函数: [DllImport( "oleacc.dll" )] public static extern int AccessibleObjectFromWindow( IntPtr hwnd, int dwObjectID, ref Guid refID, ref Accessibility.IAccessible ppvObject ); [D

我正在使用这两个本机win32函数:

    [DllImport( "oleacc.dll" )]
    public static extern int AccessibleObjectFromWindow(
            IntPtr hwnd,
            int dwObjectID,
            ref Guid refID,
            ref Accessibility.IAccessible ppvObject );
    [DllImport( "oleacc.dll" )]
    public static extern uint AccessibleChildren(
        Accessibility.IAccessible paccContainer,
        int iChildStart, 
        int cChildren,
        [Out] object[] rgvarChildren,
        out int pcObtained );
我很难确定是否应该/需要对任何返回的对象调用Marshal.ReleaseComObject。如果有人能在这个话题上启发我,我将不胜感激!下面是一个示例用法:

    Accessibility.IAccessible test(
        int hWnd,
        string accessName )
    {
        Guid guidCOM = new Guid( 0x618736E0, 0x3C3D, 0x11CF, 0x81, 0xC, 0x0, 0xAA, 0x0, 0x38, 0x9B, 0x71 );
        Accessibility.IAccessible a = null;

        AccessibleObjectFromWindow(
            new IntPtr( hWnd ),
            -4,
            ref guidCOM,
            ref a );
        object[] children = new object[a.accChildCount];
        int z;
        AccessibleChildren( a, 0, children.Length, children, out z );
        foreach ( Accessibility.IAccessible a2 in children )
            try
            {
                if ( a2.get_accName( 0 ) == accessName )
                    return a2;
            }
            catch
            {
            }
        return null;
    }

如果您确实需要让GC立即应用发布,而不是等待GC运行,则封送.ReleaseComObject是一个有用的解决方法。除非您真的需要,否则最好不要使用它,因为它有接管代码的倾向,您必须在任何地方应用它,包括创建隐式引用的地方

我怀疑.Net中COM互操作的最佳方法是围绕所使用的方法编写强类型包装器类。这样就不可能引入隐式引用,并且它将简化代码并确保GC更容易访问接口。我的一些cow工作人员报告说,通过使用这种方法,他们的内存表现更好——当GC运行时,对象会及时释放,而不会留下任何神秘的引用


一般来说,.Net代码中引用的所有COM对象都以RCW对象的形式实现,该对象保存真正的COM引用-对
ReleaseComObject
的调用将强制RCW将引用减少一个计数。这样做类似于在实际的
IUnkown
实例上调用
Release
。可能在上面的示例中,没有必要打电话。

最好不要使用它,这一点非常具体。例如,在处理Outlook加载项时,几乎所有内容都必须手动发布。不这样做会导致一些非常奇怪的错误(“过度发布”也是如此,因此需要在代码中计算出非常精确的所有权语义)。看……另一方面。事实上,pst,在我看来,VS团队冗长的故事是一个特例。你引用的这篇文章引用了这个较短的故事:。它为使用Marshal.ReleaseComObject提出了一些简单、易于遵循的规则。