簡體   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