后台Excel线程没有被杀死C#

时间:2016-05-10 14:06:09

标签: c# .net asp.net-mvc excel background-process

需要使用Excel Interop。我可以成功打开并读取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();

按照上面的代码,我在调试器中得到以下异常

watch 'application' in VS debugger

对此有任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

您正在使用range.Rows.Count,这可能违反了“绝不使用带有com对象的2个点”。规则。 See here

您可以尝试包含此内容;

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 

答案 1 :(得分:0)

我不得不使用Excel互操作,我在遵循这些简单规则时没有遇到任何问题:

  1. 始终在try-finally中包装任何Excel互操作 块。在finally块中放置所有释放逻辑。
  2. 使用Marshal.FinalReleaseComObject释放命名的COM 引用它本质上为你做了引用计数循环。
  3. 急切地将COM对象从最深处释放到 浅。在您的情况下,我会从range开始,然后worksheet 然后是workbook等等。
  4. 使用GC.Collect()GC.WaitForPendingFinalizers()正确释放未引用的COM对象(双点规则)。手动执行之前 释放挂起的COM对象,您拥有一个命名引用。