Reputation: 798
Will be all unmanaged COM objects released in case if I use code like this
var worksheet = new Application().Workbooks.Add().Worksheets.Add();
Marshal.ReleaseComObject(worksheet);
instead of code like this
var excel = new Application();
var workbook = excel.Workbooks.Add();
var worksheet = workbook.Worksheets.Add();
Marshal.ReleaseComObject(excel);
Marshal.ReleaseComObject(workbook);
Marshal.ReleaseComObject(worksheet);
?
If there is some documentation please send a link in answer.
Upvotes: 3
Views: 90
Reputation: 12181
Actually, both code samples will leave an Excel process running in the background. You need to call Application.Quit()
on the application object, for example. The following works:
private static void DoExcel()
{
var application = new Application();
var workbook = application.Workbooks.Add();
var worksheet = workbook.Worksheets.Add();
// Name that this will be saved as
string name = workbook.FullName + ".xlsx";
string fullPath = Path.Combine(Directory.GetCurrentDirectory(), name);
// If a file of the same name exists, delete it so that we won't be prompted if
// we want to overwrite it when we save
if (File.Exists(fullPath))
File.Delete(fullPath);
// Save the workbook - otherwise we may be prompted as to whether we want to save when we go to quit
workbook.Save();
// Quit the application
application.Quit();
// Release the references
Marshal.ReleaseComObject(worksheet);
Marshal.ReleaseComObject(workbook);
Marshal.ReleaseComObject(application);
// Release the .NET reference and run the garbage collector now to make sure the application is closed immediately
worksheet = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
A few other good things to remember: I didn't use it here, but there's a Marshal.FinalReleaseComObject method that's very useful in these cases. Also, again I didn't use this in my code sample, but the Marshal.ReleaseComObject
method returns the current count, so you could always do the release in a loop if you wanted to make sure the count reached zero:
while (Marshal.ReleaseComObject(comObject) > 0) { }
You can also use this for debugging purposes - e.g.
int count = Marshal.ReleaseComObject(comObject);
Trace.TraceInformation("Current COM object reference count: " + count.ToString());
Upvotes: 1