释放Com对象

时间:2015-07-07 16:12:01

标签: c# excel com interop

即使在我通过代码清理(或认为我正在清理)之后,EXCEL应用程序在任务管理器中保持打开也存在问题。任何人都可以从下面的代码片段中指出我所遗漏的内容:

private void btnBrowseSquid_Click(object sender, EventArgs e)

        //starting up and defining the Excel references
        Excel.Workbook squidBook = null;
        Excel.Application excelApp = null;
        Excel.Worksheet squidSheet = null;
        string squidFileName = txtSquid.Text;

        //Reading the information from the "Filenames" tab of the SQUID file into the Windows Form
        excelApp = new Excel.Application();
        excelApp.Visible = true;
        squidBook = excelApp.Workbooks.Open(squidFileName);
        squidSheet = squidBook.Sheets["Filenames"];

        //do stuff here with the excel file

        //close the open Excel App
        squidBook.Close();
        excelApp.Quit();
        Marshal.FinalReleaseComObject(squidSheet);
        Marshal.FinalReleaseComObject(squidBook);

    }

4 个答案:

答案 0 :(得分:0)

还要执行以下操作:

Worksheets sheets = excelApp.Worksheets; 
Marshal.ReleaseComObject(squidSheet);
Marshal.ReleaseComObject(squidBook );
Marshal.ReleaseComObject(sheets);
squidSheet = null;
squidBook = null;
sheets = null;
GC.Collect();
GC.WaitForPendingFinalizers();

您必须通过执行以下声明来释放工作表:

squidSheet = squidBook.Sheets["Filenames"];

答案 1 :(得分:0)

您可能在失败的尝试中有一个旧过程,而您的代码没有到达终点....

在运行代码之前尝试完成。 (确保您没有打开其他Excel应用程序)。

当您确定您的代码永远不会失败时,运行它并看到应用程序从进程列表中消失。

答案 2 :(得分:0)

使用Office Interop可能很棘手,因为清理代码中存在很多错误。您是否尝试过将代码减少到最低限度并向外扩展直到问题再现(例如创建应用程序,退出应用程序; Excel.exe是否挂出?创建应用程序,加载工作簿,关闭工作簿,退出应用程序; Excel.exe挂出了吗?...)?

所有这一切,上次我遇到这个问题(使用Outlook)的根本原因是因为默认的互操作层没有正确释放事件挂钩 - 所以我必须明确地这样做。准备一些挫败感,但通过一些实验,你应该能够将其运行起来。

答案 3 :(得分:0)

我能够遵循@Philip建议并取消ExcelApp,然后释放COM对象,如下所示,并且它有效。谢谢你的帮助。

 //close the open Excel App
        squidBook.Close();
        excelApp.Quit();
        Marshal.FinalReleaseComObject(squidSheet);
        Marshal.FinalReleaseComObject(squidBook);
        Marshal.FinalReleaseComObject(excelApp);
        excelApp = null;
        squidSheet = null;
        squidBook = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();