释放 Com 对象
Releasing Com Objects
我遇到了一个问题,即 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);
}
同时执行以下操作:
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"];
你可能有一个旧的过程,因为你的代码没有到达终点,但尝试失败了....
尝试在 运行 编写代码之前完成它。 (确保您没有打开其他 excel 应用程序)。
当您确定您的代码永远不会失败时,运行 它会看到应用程序从进程列表中消失。
使用 Office Interop 可能会很棘手,因为清理代码中存在很多错误。您是否尝试过将代码减少到最低限度并向外扩展,直到问题重现(例如,创建应用程序,退出应用程序;Excel.exe 闲逛吗?创建应用程序,加载工作簿,关闭工作簿,退出app;Excel.exe 出去玩了吗?...)?
总而言之,上次我遇到这个问题(使用 Outlook)时,根本原因是因为默认的互操作层没有正确释放事件挂钩 - 所以我必须明确地这样做。为一些挫折做好准备,但通过一些实验,您应该能够 运行 降低它。
我听从了@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();
我遇到了一个问题,即 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);
}
同时执行以下操作:
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"];
你可能有一个旧的过程,因为你的代码没有到达终点,但尝试失败了....
尝试在 运行 编写代码之前完成它。 (确保您没有打开其他 excel 应用程序)。
当您确定您的代码永远不会失败时,运行 它会看到应用程序从进程列表中消失。
使用 Office Interop 可能会很棘手,因为清理代码中存在很多错误。您是否尝试过将代码减少到最低限度并向外扩展,直到问题重现(例如,创建应用程序,退出应用程序;Excel.exe 闲逛吗?创建应用程序,加载工作簿,关闭工作簿,退出app;Excel.exe 出去玩了吗?...)?
总而言之,上次我遇到这个问题(使用 Outlook)时,根本原因是因为默认的互操作层没有正确释放事件挂钩 - 所以我必须明确地这样做。为一些挫折做好准备,但通过一些实验,您应该能够 运行 降低它。
我听从了@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();