C#Excel自动化导致Excel内存泄漏
我正在尝试使用C#与COM互操作库打开一套非常沉重的Excel工作簿。 我必须使用C#,因为我还需要启动macros,移动一些单元格,并开始一个自定义的Excel加载项,我的公司使用。
然后我的程序退出,将工作簿打开,每个都在一个单独的excel实例中。 当程序退出时,我不希望工作簿被closures。
问题是,当我的C#程序退出,随着时间的推移,Excel工作簿逐渐消耗更多的内存,直到他们从原来的500 MB内存消耗3.5演唱会的内存。
我曾经手工打开工作簿,工作表从未消耗过多的内存。 一旦我开始使用C#打开它们,由于内存使用量过大,它们开始中断。 我的理论是,当我与COM Excel对象交互时,我创build了一个内存泄漏。
以下是我的原始代码:
using Excel = Microsoft.Office.Interop.Excel; ... excelApp = new Excel.Application(); excelApp.Visible = true; excelApp.Workbooks.Open(filename, misValue, misValue, misValue, misValue, misValue, true, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue); excelApp.Calculation = Excel.XlCalculation.xlCalculationAutomatic;
我阅读了关于如何使用Marshal来释放使用的信息,所以现在我正在尝试下面的代码,但是除了打开所有的表格并且看看它们是否消耗了太多的数据之外,没有简单的方法来testing它。
excelApp = new Excel.Application(); excelApp.Visible = true; Excel.Workbooks currWorkbooks = excelApp.Workbooks; Excel.Workbook currWorkbook = currWorkbooks.Open(filename, misValue, misValue, misValue, misValue, misValue, true, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue); //excelApp.Calculation = Excel.XlCalculation.xlCalculationAutomatic; int x = Marshal.ReleaseComObject(currWorkbook); currWorkbook = null; int y = Marshal.ReleaseComObject(currWorkbooks); currWorkbooks = null;
当使用MS Office COM Interop库时,我遇到了一些避免内存泄漏的事情:
首先,“不要使用两个点”是记住它的最好方法,但基本上,总是为新variables分配一个新的COM对象引用,即使Intellisense鼓励它,也不要链式调用成员。 链接调用在背景中做了一些阻止.NET框架正确发布的东西。下面是一些用于启动Excel报告的代码:
//use vars for every COM object so references don't get leftover //main Excel app var excelApp = new Application(); var workbooks = excelApp.Workbooks; //workbook template var wbReport = workbooks.Add(@"C:\MyTemplate.xltx"); //Sheets objects for workbook var wSheetsReport = wbReport.Sheets; var wsReport = (Worksheet)wSheetsReport.get_Item("Sheet1");
其次,为创build的每个variables调用Marshal.ReleaseComObject()
,然后在创build之前调用一些垃圾收集方法:
//garbage collector GC.Collect(); GC.WaitForPendingFinalizers(); //cleanup Marshal.ReleaseComObject(wsReport); Marshal.ReleaseComObject(wSheetsReport); Marshal.ReleaseComObject(wbReport); Marshal.ReleaseComObject(workbooks); Marshal.ReleaseComObject(excelApp);
每当我使用Excel时,使用这个scheme解决了我的记忆问题,尽pipe它是单调乏味的,但我们不能像以前那样使用链接成员。
- 使用Excel.interop从C#中的Excel工作表中select透视表中的列filter值
- 通过C#中的名称引用更新Excel单元格值
- 使用Interop创buildExcel图表 – 更新到Office 2013时出错
- Excel Interop Range.Value = arr 当arr 包含date小于1900-01-01时与0x800A03EC崩溃
- 使用Microsoft.Office.Interop保存用C#创build的文件
- 即使VBA由Excel实例打开,也附加到现有的Excel实例
- 将generics数组转换为特定的types
- 从另一个线程访问Excel对象模型
- CSV到Excel文件?