How to properly clean up Excel interop objects in C#

It is common issue for who develops applications using Excel. As regular developing process, you create Excel objects for your Excel tasks. Then you remove these objects when you’re done with them.

The problem is that they don’t go away even you remove them! They stay at background. You see them at Task Manager:

After a while, you will see bunch of EXCEL.EXE processes running at background. So, is that the all we can do? Of course, it isn’t. Here is the solution:

Solution for cleaning up Excel interop objects

Actually, there several ways to clean them up. The thing is that none of them might not work or first one you have tried may work. Therefore, you should try all the ways below without giving up.

Your class for Excel tasks

It may looks like this:
Excel._Application app = new Excel.Application();
Excel._Workbook workbook = app.Workbooks.Add(Type.Missing);
Excel._Worksheet worksheet = null;
app.Visible = true;

worksheet.Cells[1, 1] = "test string";

workbook.SaveAs("C:\testfile.xlsx");

object misValue = System.Reflection.Missing.Value;
workbook.Close(true, misValue, misValue);
app.Quit();

releaseObject(worksheet);
releaseObject(workbook);
releaseObject(app);

Your class for releasing objects

You may be using a class to release objects:

private void releaseObject(object obj)
{
    try
    {
        System.Runtime.InteropServices.Marshal.FinalReleaseComObject(obj);
        obj = null;
    }
    catch (Exception ex)
    {
        obj = null;
        MessageBox.Show("Unable to release the Object " + ex.ToString());
    }
    finally
    {
        GC.Collect();
    }
}

Option 1: Give more time to the application

Change finally block in releaseObject class with this:

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

Garbage Collecter will wait for pending operations and try twice.

Option 2: Do not open Excel file in the same line

If you are opening an existing Excel file, use the code like this:

Worksheets sheets = excelApp.Worksheets; // <-- the important part
Worksheet sheet = sheets.Open(...);

Instead of this:

Worksheet sheet = excelApp.Worksheets.Open(...);

Using two dots with COM objects is not recomended.

Option 3: Use Application.Quit as well

Like this:

app.Application.Quit();
app.Quit();

Option 4: Set objects to null, if you don’t need them

It may be helpful for the Garbage Collector

worksheet = null;
workbook = null;
app = null;

I know, you’re already setting them to null in releaseObject class. This is for double check.

Option 5: Make sure that you release all objects related to Excel

If you don’t release all objects, none of the options above can help you. Make sure you release all objects including range one!

Excel.Range rng = (Excel.Range)worksheet.Cells[1, 1];
worksheet.Paste(rng, false);
releaseObject(rng);

In this case, we are using Excel.range and releasing it.

Summary

This problem has been annoying developer for a few years. You can figure it out by using the information above.

If you still face this problem, try killing EXCEL.EXE process. I don’t recommend it because it may end up with killing Excel files which isn’t related to your application

3 thoughts to “How to properly clean up Excel interop objects in C#”

Leave a Reply