1

Trying to figure out why my EXCEL*32 process remains in use until both the my application AND the excel file are closed. I must be missing something after creation, it's like the application is holding onto the EXCEL *32 resource after this code. Any suggestions to get it to 'let go' after it's export operation is completed?

Also, I do not want to close the newly created Excel sheet, I just want to release the resource being used in relation to my actual .net application.

Application xls = new Application();
xls.SheetsInNewWorkbook = 1;

// Create our new excel application and add our workbooks/worksheets
Workbook Workbook = xls.Workbooks.Add();
Worksheet CrossoverPartsWorksheet = xls.Worksheets[1];

// Create our new excel application and add our workbooks/worksheets
Workbook Workbook = xls.Workbooks.Add();
Worksheet CrossoverPartsWorksheet = xls.Worksheets[1];

/////////////////////////////////////////
// < DO EXCEL EXPORT OPERATIONS HERE > //
/////////////////////////////////////////

// Release our resources.
Marshal.ReleaseComObject(Workbook);
Marshal.ReleaseComObject(CrossoverPartsWorksheet);
Marshal.ReleaseComObject(xls);
Volearix
  • 1,573
  • 3
  • 23
  • 49
  • Duplicate of http://stackoverflow.com/questions/158706/how-to-properly-clean-up-excel-interop-objects ? – Keith Payne Sep 05 '13 at 17:33
  • Already looked at this one which is where I got the Marshal.ReleaseComObject part from. – Volearix Sep 05 '13 at 17:34
  • This is just not the right way to do this. Call GC.Collect() instead. And read [this answer](http://stackoverflow.com/questions/17130382/understanding-garbage-collection-in-net/17131389#17131389) to understand why that doesn't work when you put it at the end of the method. Put it in the caller method instead. – Hans Passant Sep 05 '13 at 17:59
  • I am able to avoid GC all together, which is ideal when it isn't actually required, per the accepted answer in which @Dmitry Martovoi has provided. – Volearix Sep 06 '13 at 13:40

2 Answers2

2

When you write

Workbook Workbook = xls.Workbooks.Add();

CLR creates RCW (Runtime Callable Wrapper) objects not only for Workbook, but for Workbooks collection too(coz you need object that then will be used for Add() method). And if CLR creates RCW object and you do not keep reference - you can't finalize it.

So, the main rule: You should avoid double-dot-calling expressions:

var workbooks = xls.Workbooks;
var workbook = workbooks.Add();

Marshal.ReleaseComObject(workbook);
Marshal.ReleaseComObject(workbooks);
Dzmitry Martavoi
  • 6,867
  • 6
  • 38
  • 59
  • BOOM! This works, did not realize there was a RCW with that (Didn't even know what that was to be honest). – Volearix Sep 05 '13 at 17:42
0

Marshal.FinalReleaseComObject(xls) is what your looking for.

OneFineDay
  • 9,004
  • 3
  • 26
  • 37
  • Still doesn't release in task manager until the .net application is closed. Hence, I create 3 different Excel exports and close all 3, all are still showing as running processes until I quit the application. – Volearix Sep 05 '13 at 17:36
  • Not sure what your doing wrong then, I have tested this many times. Make sure you quit the app and dispose all excel objects with this method. – OneFineDay Sep 05 '13 at 17:38
  • I think that's the problem, just in what you said there. I'm not wanting to quit anything. I want to leave the excel app open as well as the excel export app, just don't want the app to hold onto the resource. Am I making sense with that? – Volearix Sep 05 '13 at 17:40