CtrlDot
CtrlDot

Reputation: 3122

Can I create a generalized method to release COM objects?

Given the following code, will the ReleaseCOMObj() method release the original COM object, or will it implicitly create a copy and release that?

private void TestRelease()
{
    Excel.Workbook workbook = excel.ActiveWorkbook;
    // do stuff
    ReleaseComObj(workbook);
}

private static void ReleaseComObj(Object obj)
{
    if (obj != null)
    {
        Marshal.ReleaseComObject(obj);
        obj = null;
    }
}

Update: Changed method to static. See Passing COM objects as parameters in C# for an explanation as to why the Object parameter cannot be ref Object obj.

Upvotes: 1

Views: 248

Answers (2)

shf301
shf301

Reputation: 31394

If you want to set the reference to null you can use a generic method like:

 private static void ReleaseComObj<T>(ref T obj) where T:class  {
        if (obj != null) {
            Marshal.ReleaseComObject(obj);
            obj = null;
        }
    }

Although setting the reference to null isn't needed. The COM object will be released in any case. See the documentation for RealeaseComObject(). You may also want to consider calling FinalReleaseComObject().

Also you could create a wrapper object that implements IDisposable and use a using block to ensrue the COM object is released even if there is an exception.

class ComObjectCleanUp : IDisposable {

    private T obj;

    public ComObjectCleanUp(T obj) {
        this.obj = obj;
    }

    public void Dispose() {
        if (obj != null)
            Marshal.FinalReleaseComObject(obj);
    }
}

And your code becomes:

private void TestRelease()
{
    Excel.Workbook workbook = excel.ActiveWorkbook;
    using (var c = new ComObjectCleanUp(workbook))
    {
        // do stuff
    }
}

Although I will admit that isn't very pretty, especially considering the number of COM objects you will reference using Office automation, but it's an idea anyway.

Upvotes: 1

SLaks
SLaks

Reputation: 887365

C# parameters are passed by reference.

Therefore, it will release the original COM object, but it won't set the original variable to null.

To set the original variable to null, change it to a ref parameter, which passes a variable by reference. (and call it with the ref keyword)

Also, by the way, the method should be static, since it doesn't use this.

Upvotes: 1

Related Questions