Search code examples
c#dispose

C# cleanup unmanaged resources when process is killed


I have a class that instantiates a COM exe out of process. The class is

public class MyComObject:IDisposable
{
    private bool disposed = false;
    MyMath test;

    public MyComObject()
    {
        test = new MyMath();
    }

    ~MyComObject()
    {
        Dispose(false);
    }

    public double GetRandomID()
    {
        if (test != null)
            return test.RandomID();
        else
            return -1;
    }

    public void Dispose()
    {
        Dispose(true);

        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
       if (test != null)
       {
           Marshal.ReleaseComObject(test);
           test = null;
       }

       disposed = true;
    }
}

and I call it as follows

static void Main(string[] args)
    {
        MyComObject test = new MyComObject();
        MyComObject test2 = new MyComObject();

        //Do stuff

        test.Dispose();
        test2.Dispose();

        Console.ReadLine();
    }

now, this cleans up my COM object when the program executes normally. However, if I close the program in the middle of its execution, the framework doesn't ever call the code that releases my unmanaged object. Which is fair enough. However, is there a way to force the program to clean itself up even though its been killed?

EDIT: it doesn't look promising from a hard kill from the taskmanager :(


Solution

  • Wrapping it in a try finally or using clause will get you most of the way there:

    using (MyComObject test = new MyComObject())
    using (MyComObject test2 = new MyComObject()) {
        // do stuff
    }
    Console.ReadLine();
    

    The specifics of how your app is being shutdown, though, will dictate any other measures you can do (like using CriticalFinalizerObject).

    I think that a console app that gets closed (from the little x) is the same as a Ctrl-C - in which case you can subscribe to Console.CancelKeyPress for that.

    Edit: You should also ReleaseComObject until it returns <= 0.