问题:
当用如下代码操作完Excel,虽然调用了Application的Quit()方法,但发现Excel进程并没退出。
object missing = System.Reflection.Missing .Value;
Application app = new Application();
app.Visible = false ;
app.UserControl = true ;
Workbook wb = app.Workbooks.Open(path, missing, true , missing, missing, missing, missing,
missing, missing, true , missing, missing, missing, missing, missing);
Worksheet ws = (Worksheet )wb.Worksheets.get_Item(1);
Console .WriteLine(ws.Cells[2,1].Value);
ws.Close();
ws = null;
app.Quit();
app = null;
结果:
原因:
When Visual Studio .NET calls a COM object from managed code, it automatically creates a Runtime Callable Wrapper (RCW). The RCW marshals calls between the .NET application and the COM object. The RCW keeps a reference count on the COM object. Therefore, if all references have not been released on the RCW, the COM object does not quit.
解决方案:
1、为每一个对象定义一个变量。
例如:
把这段代码
Workbook wb = wbs.Open(path, missing, true , missing, missing, missing, missing,
missing, missing, true , missing, missing, missing, missing, missing);
改为
Workbooks wbs = app.Workbooks;
Workbook wb = wbs.Open(path, missing, true , missing, missing, missing, missing,
missing, missing, true , missing, missing, missing, missing, missing);
2、当使用完com对象对其循环调用System.Runtime.InteropServices.Marshal.ReleaseComObject 直到返回值为0
3、设置变量位null
4、调用Quit方法通知服务器关闭
5、调用GC .Collect();
最终:
把上边的代码修改为:
public static void ExcelRead(string path)
{
object missing = System.Reflection.Missing.Value;
Application app = new Application();
app.Visible = false;
app.UserControl = true;
Workbooks wbs = app.Workbooks;
Workbook wb = wbs.Open(path, missing, true, missing, missing, missing, missing,
missing, missing, true, missing, missing, missing, missing, missing);
Sheets wss = wb.Worksheets;
Worksheet ws = (Worksheet)wss.get_Item(1);
Console.WriteLine(ws.Cells[2,1].Value);
NAR(ws);
ws = null;
NAR(wss);
wss = null;
wb.Close();
NAR(wb);
wb = null;
wbs.Close();
NAR(wbs);
wbs = null;
app.Quit();
NAR(app);
app = null;
GC.Collect();
}
private static void NAR(object o)
{
try
{
while (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) ;
}
catch
{ }
finally
{
o = null;
}
}
结果能正常关闭Excel进程。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)