简体   繁体   中英

Writing the correct IDisposable implementation for classes with COM objects

I have a class that uses a .NET wrapper for a COM object and well it is giving me that infamous RCW error, so in my investigation I found that if I take out the Dispose() method from the finalizer of this class it will fix the RCW error so something is wrong for example the object is getting disposed but the registered events are still hanging around ... But just removing the Dispose() can't be the answer because then who is going to release the memory ? ( I ran a Memory profiler and confirmed that just removing the Dispose method causes like 20MB of extra Unmanaged Memory )

so something should be wrong with the way I am using the Dispose model.. here is what I have:

  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;
        }
    }

For COM objects, you'll want to call Marshal.ReleaseComObject . The Marshal class is found in the namespace System.Runtime.InteropServices .

More info here .

Unmanaged resources should be disposed outside of the if(disposing) part. In there only managed resources should be disposed.

In the COM wrapper:

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

            //Release the unmanaged resource.

            disposed = true;
        }
    }

and keep your implementation of the Dispose Pattern as is since the COM wrapper implements IDisposable.

I'm not sure about ReleaseComObject . It is not allways recommended apparently. There is also the Marshal.FinalReleaseComObject method. Also have a look at this answer on how to wrap a COM object.

For detailed guidelines on how to implement the dispose pattern you can read this blog entry by Joe Duffy. It is rather long but very helpful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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