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它是单调乏味的,但我们不能像以前那样使用链接成员。