Checking to see if a Com object was released

G

greg.merideth

There's a utility application I have that generates Excel files for the
end users that 99% of the time works just fine.

The problem I've encountered is when placing a lot of data (and by a
lot I mean creating 90+ tabs and filling each worksheet with 4-5,000
values with misc formatting per sheet) an exception is thrown when I
attempt to release the worksheet using:

System.Runtime.InteropServices.Marshal.ReleaseComObject(xlInvSheet);

The "giveaway" on this is that when testing, I will notice an excel.exe
staying in memory after the 4-5th Excel creation which is then followed
by a crash.

During the day, my app will create 20-30 spreadsheets using Excel while
encountering no issues. It's just "every now and then" that a rogue
excel.exe stays and then corrupts the next attempt.

So, is there a way to see if a Com object has not been cleared by the
GC and somehow force a second clearing or possibly warn the user to
exit, kill the rogue excel (for now at least) and start again?

After releasing the sheets, workbook and Excel App, I do a call to
GC.Collect() and from what I've experimented with I can't see anything
else I should be doing to prevent these rogue excel's.
 
O

Ollie Riches

There are lots of posting about using COM object in managed code and the
issues around resource handling\releasing.

I am currently working on a system that uses COM+ components via interop
that create a large number of threads and allocate a large amount memory
internally and if I don't call the following code when I have finished with
the COM components then they don't release there resources in a timely
manner - they are used in a object pool secenario so it leaks a large amount
of resources very quickly.

The code below is executed (in the finally of a try\catch block) when I have
finished with the COM components:

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

In general you should not have to call any of the above code in a 'normal'
..net application, but sometimes it is required. There is a performance
penalty for calling the above code but if you can live with that then it
might help yuor problem.

HTH

Ollie Riches
 
G

greg.merideth

I'll add a call to GC.WaitForPendingFinalizers() to the code and run an
automated test to see what happens. Performance on closing isn't that
much of an issue so I will try anything.

I was under the impression that WaitForPendingFinalizers will operate
in a blocking fashion preventing code from running until the GC calls
the finalize processes for all objects in the COM component. Can this
be threaded in some way or fired as an async process so the application
can still process or is this dangerous? Or does a call to
WaitForPendingFinalizers not create a noticable delay?

Thanks for the reply.
 
O

Ollie Riches

yes it will suspend all code executing until it has finished and no you
can't get round this

HTH

Ollie Riches
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top