In a C # program I work with an Excel workbook as follows.

using Excel = Microsoft.Office.Interop.Excel; Excel.Application excel; excel = new Excel.Application(); excel.Workbooks.Open( "1.xlsx"); Excel.Worksheet sheet = (Excel.Worksheet)excel.ActiveSheet; //Читаю некоторые ячейки excel.ActiveWorkbook.Save(); excel.ActiveWorkbook.Close(); excel.Quit(); GC.Collect(); 

After executing this code, the EXCEL.EXE process continues to hang in the task manager, but it terminates after my program is closed. If you remove the last 3 lines, the process hangs in the manager and does not end after closing my program. How to properly close Excel?

    2 answers 2

    You must free all used COM objects using Marshal.ReleaseComObject .

    In addition, there is a rule:

    Never use two points with COM objects.

    When you write:

     excel.Workbooks.Open( "1.xlsx"); 

    it actually creates two COM objects. Both need to be released after finishing work with them. Therefore, it is necessary to break this expression into two, with each COM object stored in a variable.

    In addition, it is desirable to provide a guaranteed exemption even in the case of exceptions. The final code might look something like this:

     Workbooks workbooks = null; Workbook workbook = null; try { workbooks = excel.Workbooks; workbook = workbooks.Open( "1.xlsx"); } finally { Marshal.ReleaseComObject(workbook); Marshal.ReleaseComObject(workbooks); } 

    So you need to do with all used COM objects.

    Your Excel code should be located in a try block, the close code and the release of all resources used should be in a finally block.

    • Yes, you are right, but I had a mistake in the other. In my case, Excel opens twice in one function: the first time to load data, then calculations are performed, and after that Excel opens a second time to save. In this case, Excel hangs in the dispatcher even after performing the specified steps. This is probably the job of the optimizer. Now I have taken out the loading and saving into separate functions and the problem has disappeared. - maestro
    • @maestro - Interesting. You can make your decision as an answer (and even accept it, instead of mine). And you can well earn a plus sign, because it really is useful to others in the future. - Alexander Petrov
     if (application != null) { application.WorkbookBeforeClose -= new Excel.AppEvents_WorkbookBeforeCloseEventHandler(application_WorkbookBeforeClose); application.Quit(); Marshal.ReleaseComObject(application); GC.Collect(); GC.WaitForPendingFinalizers(); process.WaitForExit(100); }