繁体   English   中英

为带有COM对象的类编写正确的IDisposable实现

[英]Writing the correct IDisposable implementation for classes with COM objects

我有一个使用.NET包装器作为COM对象的类,它给了我那个臭名昭著的RCW错误,因此在调查中,我发现如果我从此类的终结器中取出Dispose()方法,它将可以修复RCW错误,所以出了点问题,例如对象被处置,但是注册的事件仍然悬而未决……但是仅仅删除Dispose()并不能解决问题,因为谁将释放内存? (我运行了一个内存探查器,并确认仅删除Dispose方法会导致大约20MB的额外非托管内存)

所以我使用Dispose模型的方式应该有问题。这就是我所拥有的:

  private MyCOMobject theCOMobject = null;

    static SuppressFieldCntrlr()
    {
        new SomeCalss();
    }

    ~SuppressFieldCntrlr()
    {
       Dispose(false); 
    }



    private bool disposed = false;

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                theCOMobject.Dispose();
            }

            MethodFoo(false);

            disposed = true;
        }
    }

对于COM对象,您需要调用Marshal.ReleaseComObject 元帅类位于名称空间System.Runtime.InteropServices

更多信息在这里

非托管资源应放在if(disposing)部分之外。 在该处仅应处理托管资源。

在COM包装器中:

private void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                //Dispose managed resource if any.                   
            }

            //Release the unmanaged resource.

            disposed = true;
        }
    }

并保持您对Dispose Pattern的实现保持原样,因为COM包装器实现了IDisposable。

我不确定ReleaseComObject 显然并非始终建议这样做 还有Marshal.FinalReleaseComObject方法。 也可以看看有关如何包装COM对象的答案

有关如何实现处置模式的详细指南,您可以阅读Joe Duffy的博客文章 它相当长,但是非常有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM