Properly clean up excel interop objects revisited: Wrapper objects

Posted by chiccodoro on Stack Overflow See other posts from Stack Overflow or by chiccodoro
Published on 2010-05-04T17:09:38Z Indexed on 2010/05/04 17:38 UTC
Read the original article Hit count: 722

Filed under:
|
|
|

Hi all,

All of these struggle with the problem that C# does not release the Excel COM objects properly after using them. There are mainly two directions of working around this issue:

  1. Kill the Excel process when Excel is not used anymore.
  2. Take care to assign each COM object used explicitly to a variable and to Marshal.ReleaseComObject all of these.

Some have stated that 2 is too tedious and there is always some uncertainty whether you forget to stick to this rule at some places in the code. Still 1 seems dirty and dangerous to me, also I could imagine that in an environment with restricted access killing processes is not allowed.

So I've been thinking about solving 2 by creating another proxy object model which mimics the Excel object model (for me, it would suffice to implement the objects I actually need). The principle would look as follows:

  • Each Excel Interop class has its proxy which wraps an object of that class.
  • The proxy releases the COM object in its destructor.
  • The proxy mimics the interface of the Interop class (maybe by inheriting it).
  • Any methods that usually return another COM object return a proxy instead. The other methods simply delegate the implementation to the inner COM object.

This is a rough sketch of the code:

public class Application : Microsoft.Office.Interop.Excel.Application
{
    private Microsoft.Office.Interop.Excel.Application innerApplication
        = new Microsoft.Office.Interop.Excel.Application innerApplication();

    ~Application()
    {
        Marshal.ReleaseCOMObject(innerApplication);
    }

    public Workbooks Workbooks
    {
        get { return new Workbooks(innerApplication.Workbooks); }
    }
}

public class Workbooks
{
    private Microsoft.Office.Interop.Excel.Workbooks innerWorkbooks;

    Workbooks(Microsoft.Office.Interop.Excel.Workbooks innerWorkbooks)
    {
        this.innerWorkbooks = innerWorkbooks;
    }

    ~Workbooks()
    {
        Marshal.ReleaseCOMObject(innerWorkbooks);
    }
}

My questions to you are in particular:

  • Who finds this a bad idea and why?
  • Who finds this a gread idea? If so, why hasn't anybody implemented/published such a model yet? Just due to the effort, or am I missing a killing problem with that idea?
  • Is it impossible/bad/dangerous to do the ReleaseCOMObject in the destructor? (I've only seen proposals to put it in a Dispose() rather than in a destructor - why?)
  • If the approach makes sense, any suggestions to improve it?

© Stack Overflow or respective owner

Related posts about excel

Related posts about interop