我正在开发一个 .NET 程序,该程序启动一个新的 Excel 实例,执行一些工作,然后结束,但必须让 Excel 保持运行。稍后,当程序再次运行时,它将尝试 Hook 到前一个实例。
在这种情况下处理 COM 对象释放的最佳方法是什么?如果我第一次没有对应用程序对象执行“ReleaseComObject”,然后在第二次运行时获取事件对象,然后最终释放 com 对象,是否存在内存泄漏?
以下简化代码说明了我想要做的事情:
private Microsoft.Office.Interop.Excel.Application xlsApp;
private Microsoft.Office.Interop.Excel.Workbook xlsWb;
public void RunMeFirst()
{
//Start a new instance
System.Type oSEType = Type.GetTypeFromProgID("Excel.Application");
xlsApp = Activator.CreateInstance(oSEType);
xlsWb = xlsApp.Workbooks.Open("C:\\test1.xls");
//Do some stuff
xlsWb.Close(false);
Cleanup(ref xlsWb);
//Do not quit Excel here
//No Cleanup of xlsApp here? Is this OK?
System.Environment.Exit(0);
}
public void RunMeSecond()
{
//Hook into existing instance
xlsApp = Marshal.GetActiveObject("Excel.Application");
xlsWb = xlsApp.Workbooks.Open("C:\\test2.xls");
//Do some stuff
xlsWb.Close(false);
Cleanup(ref xlsWb);
xlsApp.Quit();
Cleanup(ref xlsApp);
System.Environment.Exit(0);
}
public void Cleanup(ref object theObj)
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
Marshal.FinalReleaseComObject(theObj);
theObj = null;
}
谢谢
最佳答案
一般来说,在使用 Office PIA 时,我发现当您拥有保存 COM 对象的实例变量时,会出现此类对象未释放的问题。在您的情况下,这些将是 xlsApp
和 xlsWb
。您不必退出 Excel 应用程序即可释放对象,但您确实必须执行以下清理过程:
Marshal.FinalReleaseComObject(xlsWb);
xlsWb = null;
Marshal.FinalReleaseComObject(xlsApp);
xlsApp = null;
GC.Collect();
包含 COM 对象的局部范围变量似乎不会导致此问题,只有实例变量才会导致此问题。我希望这有帮助!
关于c# - 当应用程序继续运行时,如何清理 .NET 中的 COM 引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5957924/