背景Excel线程没有被杀死C#
需要使用Excel Interop。 我可以成功地打开并从excel文件中读取,但是在closures它时,该excel的后台进程不会被终止。 尝试使用以前的SO链接的几个解决scheme,但没有运气! 所以我的问题是,如何杀死后台进程?
以下是我目前正在使用的UPDATED CODE :
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();
通过遵循上面的代码, 我在我的debugging器中得到下面的exception :
任何帮助,将不胜感激。
您正在使用range.Rows.Count,这可能会违反“从不使用COM对象使用2点”。 规则。 看这里
你可以尝试包括这个;
var rows = range.Rows for (int row = 2; row <= rows.Count; row++) { //Read the data from the excel } rows.Clear(); //rows is itself a range object
有几次,我不得不使用Excel互操作,我没有任何问题时遵循这些简单的规则:
- 总是将任何Excel互操作包装在
try-finally
块中。 在finally
块中放置所有的释放逻辑。 - 使用
Marshal.FinalReleaseComObject
来释放命名的COM引用,因为它本质上是为你做ref count循环的。 - 急切地从最深到最浅的COM对象释放。 在你的情况下,我会开始
range
然后worksheet
然后workbook
等。 - 使用
GC.Collect()
和GC.WaitForPendingFinalizers()
正确释放未引用的COM对象(双点规则GC.WaitForPendingFinalizers()
。 在手动释放持有命名引用的挂起COM对象之前,请执行此操作。