【发布时间】:2016-09-05 13:44:24
【问题描述】:
需要使用 Excel 互操作。我可以成功打开并从 excel 文件中读取,但是在关闭它时,该 excel 的后台进程不会被杀死。尝试使用以前 SO 链接中的几种解决方案,但没有运气!所以我的问题是,如何杀死后台进程???
以下是我目前使用的更新代码:
Excel.Application application = new Excel.Application();
var workbooks = application.Workbooks;
Excel.Workbook workbook = workbooks.Open(path);
Excel.Worksheet worksheet = workbook.ActiveSheet;
Excel.Range range = worksheet.UsedRange;
var rows = range.Rows;
// Some business logic
for (int row = 2; row <= rows.Count; row++)
{
//Read the data from the excel
}
// Some business logic
//close the excel
rows.Clear();
cell.Clear();
range.Clear();
workbook.Close(false);
application.Quit();
while (Marshal.FinalReleaseComObject(rows) != 0) { }
while (Marshal.FinalReleaseComObject(cell) != 0) { }
while (Marshal.FinalReleaseComObject(range) != 0) { }
while (Marshal.FinalReleaseComObject(worksheet) != 0) { }
while (Marshal.FinalReleaseComObject(workbook) != 0) { }
while (Marshal.FinalReleaseComObject(workbooks) != 0) { }
while (Marshal.FinalReleaseComObject(application) != 0) { }
rows = null;
cell = null;
range = null;
worksheet = null;
workbook = null;
workbooks = null;
application = null;
GC.Collect();
GC.WaitForPendingFinalizers();
按照上面的代码,我在调试器中得到以下异常:
我们将不胜感激。
【问题讨论】:
-
你没有释放
range。此外,如果您通过Marshal.ReleaseComObject、GC.Collect和GC.WaitForPendingFinalizers手动释放 RCW,则不需要。最后,使用Marshal.FinalReleaseComObject,它会在一次通话中为您完成循环。 -
另外,作为一种好的做法,倾向于将此类代码包装在
try-finally块中,以确保您在正常执行和可恢复的错误情况下正确释放所有 COM 对象。 -
@inBetween:是的,代码被包装在一个 try-catch 中,在我在这里发布之前和之后还有一些东西,认为它们不是必需的,因为它们只是用于其他一些 BL 实现:)
-
@inBetween 尝试了所有这些,但没有好的结果:( 我真的很傻,错过了一些非常小的东西??感觉很愚蠢!!:/
-
这可能根本不是,但以防万一;当我使用 Excel 互操作时,我倾向于从最深到最浅释放 COM 对象。即从范围 -> 工作表 -> 工作簿 -> 工作簿 -> .... -> 应用程序开始反转发布顺序。还可以考虑显示更多代码,也许你持有一些你没有注意到的 COM 对象的引用。
标签: c# .net asp.net-mvc excel background-process