为什么此代码导致Excel无法正常关闭?

时间:2011-02-11 01:20:17

标签: c# excel

为什么这行代码会导致Excel无法退出?

Excel.Range range = (Excel.Range)ws.Cells[1,1];

如果是因为施法,那么这段代码不会导致同样的问题吗?

Excel.Worksheet ws = (Excel.Worksheet)wb.ActiveSheet;

我试过了。但这很有效。 Excel将关闭。

如果我使用此代码。 Excel关闭。

Excel.Range range = ws.get_Range("A1","A1");

那有什么区别?是的,我知道有一百万个“如何正确关闭Excel”线程。但由于这是一个问题,而不是一个答案,我决定问一个新问题而不是问其他人的问题。

这是我的代码。但当然还有其他代码。我只是在评论所有内容并慢慢地尝试哪些行导致Excel无法关闭。我意识到即使不使用垃圾收集器,Excel仍然会关闭。我不想用大锤关闭Excel。

感谢。

Excel.Application objExcel = new Excel.Application();
Excel.Workbooks wbs = objExcel.Workbooks;
Excel.Workbook wb = wbs.Open(saveFileDialog1.FileName, Type.Missing,  Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
Excel.Worksheet ws = (Excel.Worksheet)wb.ActiveSheet;
//Excel.Range range = (Excel.Range)ws.Cells[1,1];
Excel.Range range = ws.get_Range("A1","A1");

FinalReleaseAnyComObject(range);
FinalReleaseAnyComObject(ws);
wb.Close(Type.Missing, Type.Missing, Type.Missing);
FinalReleaseAnyComObject(wb);
FinalReleaseAnyComObject(wbs);
objExcel.Quit();
FinalReleaseAnyComObject(objExcel);

目前我已经尝试过objExcel,wbs,wb和ws。这4个对象不会引起问题。

private static void FinalReleaseAnyComObject(object o)
{
    Marshal.FinalReleaseComObject(o);
    o = null;
}

我意识到你也不能重复使用这个变量。

Excel.Range range = ws.get_Range("A1","G1");
range = ws.get_Range("A1", "A1");

这将导致Excel无法正常关闭。相反,使用它。

Excel.Range range = ws.get_Range("A1","G1");
FinalReleaseAnyComObject(range);
range = ws.get_Range("A1", "A1");

1 个答案:

答案 0 :(得分:12)

有一个隐藏的Range接口指针,你看不到,Cells属性返回它。然后,将索引器表达式应用于它,取消引用该Range的默认Item属性。获得另一个范围。

这就是为什么尝试自己管理COM接口指针是一个糟糕的坏主意。相信垃圾收集器始终正确。 GC.Collect()和GC.WaitForPendingFinalizers(),如果你真的,真的想让它按需退出。请务必阅读this answer以了解在调试程序时,为什么这并不总是按预期工作。