Lifetime issue of IDisposable unmanaged resources in a complex object graph?
        Posted  
        
            by stakx
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by stakx
        
        
        
        Published on 2010-04-29T21:41:41Z
        Indexed on 
            2010/04/29
            21:47 UTC
        
        
        Read the original article
        Hit count: 431
        
This question is about dealing with unmanaged resources (COM interop) and making sure there won't be any resource leaks. I'd appreciate feedback on whether I seem to do things the right way.
Background:
Let's say I've got two classes:
A class
LimitedComResourcewhich is a wrapper around a COM object (received via some API). There can only be a limited number of those COM objects, therefore my class implements theIDisposableinterface which will be responsible for releasing a COM object when it's no longer needed.Objects of another type
ManagedObjectare temporarily created to perform some work on aLimitedComResource. They are notIDisposable.
To summarize the above in a diagram, my classes might look like this:
            +---------------+           +--------------------+
            | ManagedObject | <>------> | LimitedComResource |
            +---------------+           +--------------------+
                                                  |
                                                  o IDisposable
(I'll provide example code for these two classes in just a moment.)
Question:
Since my temporary ManagedObject objects are not disposable, I obviously have no control over how long they'll be around. However, in the meantime I might have Disposed the LimitedComObject that a ManagedObject is referring to. How can I make sure that a ManagedObject won't access a LimitedComResource that's no longer there?
            +---------------+           +--------------------+
            | managedObject | <>------> |   (dead object)    |
            +---------------+           +--------------------+
I've currently implemented this with a mix of weak references and a flag in LimitedResource which signals whether an object has already been disposed. Is there any better way?
Example code (what I've currently got):
LimitedComResource:
class LimitedComResource : IDisposable
{
    private readonly IUnknown comObject;  // <-- set in constructor
    ...
    void Dispose(bool notFromFinalizer)
    {
        if (!this.isDisposed)
        {
            Marshal.FinalReleaseComObject(comObject);
        }
        this.isDisposed = true;
    }
    internal bool isDisposed = false;
}
ManagedObject:
class ManagedObject
{
    private readonly WeakReference limitedComResource;  // <-- set in constructor
    ...
    public void DoSomeWork()
    {
        if (!limitedComResource.IsAlive())
        {
            throw new ObjectDisposedException();
            //        ^^^^^^^^^^^^^^^^^^^^^^^
            //  is there a more suitable exception class?
        }
        var ur = (LimitedComResource)limitedComResource.Target;
        if (ur.isDisposed)
        {
            throw new ObjectDisposedException();
        }
        ...  // <-- do something sensible here!
    }
}
        © Stack Overflow or respective owner