Excel 使用 Workbook.Cellls 时进程保持活动状态

Excel process remains alive when using Workbook.Cellls

在现有 excel 文件的单元格中写入内容后,后台的 excel 进程没有关闭。如果我用 worksheet.Cells[1,1]=2 注释掉该部分,那么 excel 过程将像预期的那样消失。

提前感谢您的帮助。

这是我的代码:

                Excel.Application exelApp = new Excel.Application();
                var workbooks = exelApp.Workbooks;
                Excel.Workbook workbook = null;

                workbook = workbooks.Open(fileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);


                var worksheets = workbook.Worksheets;
                Excel.Worksheet worksheet = (Excel.Worksheet)worksheets.get_Item("Einzelliste");

                //worksheet.Cells[1, 1] = 2;

                workbook.Close(true, Type.Missing, Type.Missing);
                workbooks.Close();
                exelApp.Quit();

                ReleaseObject(worksheet);                    
                ReleaseObject(worksheets);                                        
                ReleaseObject(workbook);                    
                ReleaseObject(workbooks);                                       
                ReleaseObject(exelApp);

                worksheet = null;
                worksheets = null;
                workbook = null;
                workbooks = null;
                exelApp = null;

    private static void ReleaseObject(object theObject)
    {
        System.Runtime.InteropServices.Marshal.ReleaseComObject(theObject);
    }

编辑:根据马克的建议:

                var range =worksheet.get_Range("A1");
                range.Value = 1; ReleaseObject(range);

与一些认为这个 post 是一个重复问题的建议相矛盾:我不得不说这不是因为所有对象都被正确释放并且在源代码中没有使用 "double dots"代码。垃圾收集器的建议调用也不能解决问题。

尝试使用 Range 对象访问单元格或单元格,然后再对其进行操作。然后确保释放引用该范围的 COM 对象。您还需要安排您的调用,以便在使用后立即释放 COM 对象。也尝试保存 Excel 文档中的更改,Excel 可能不会关闭,因为它正在等待用户响应以保存文件。

此外(尽管 OP 不要求),永远不要循环遍历 Excel 的单元格。为行中的单元格或列中的单元格准备对象数组的数据。对网格使用数组数组。然后使用 Range 对象设置值。

根据this link中提供的信息,我认为问题的原因可能在于以下代码行。

  Excel.Worksheet worksheet = (Excel.Worksheet)worksheets.get_Item("Einzelliste");

只是一个猜测,因为它不完全遵循 link 中的规则,但我想知道转换是否对 COM 对象做了一些有趣的事情。

link 的关键部分是:

your problem is the line.

Dim wkBook As Workbook = xlApp.Workbooks.Open("C:\test.xls

because .net needs wrapper to call com objects it really turns into

Dim wkBook As Workbook dim tmp as WorkBooks tmp = xlApp.Workbooks wkBook = tmp.Open("C:\test.xls

the tmp variable has a com ref that will not be released until its garabage collected. the rule you should use is never use 2 dots with com objects. alway create a tmp, and call ReleaseComObject() on the tmps.

当然,您的代码没有完全相同的东西,但我想知道演员表是否会在幕后引起一些奇怪的行为。