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
Hi all,
- Excel 2007 Hangs When Closing via .NET
- How to properly clean up Excel interop objects in C#
- How to properly clean up interop objects in C#
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:
- Kill the Excel process when Excel is not used anymore.
- 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