C#Excel的自动化导致Excel内存泄漏(C# Excel automation causes

2019-07-04 00:52发布

我想用C#与COM互操作库,打开一组非常沉重的Excel工作簿中。 我必须使用C#,因为我还需要启动宏,中移动的一些细胞,并启动自定义的Excel加载我公司使用。

我的程序退出,留下打开的工作簿,每一个单独的Excel实例。 我不想在程序退出时,工作簿被关闭。

问题是,我的C#程序退出时,随着时间的推移,在Excel工作簿逐渐消耗更多的内存,直到他们从原来的500 MB消耗的内存3.5演出。

我用手动打开的工作簿,张从来没有消耗的内存量。 一旦我开始使用C#打开它们,他们开始因为极度的内存使用量的突破。 我的理论是,不知怎的,当我与COM Excel对象互动,我创建了一个内存泄漏。

下面是我原来的代码:

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;

我了解你需要如何使用元帅发布用途,所以现在我想下面的代码,但没有简单的方法来测试它,比其他所有打开的表,如果他们消耗了太多的数据看到。

            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;

Answer 1:

当使用MS Office的COM互操作库,有几件事情我已经遇到避免内存泄漏:

首先,“不要用两个点”是要记住它的最好办法,但基本上,始终分配一个新的COM对象引用到一个新的变量,不要链调用成员,即使智能感知鼓励它。 链式调用做一些事情在由.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");

其次,呼叫Marshal.ReleaseComObject()在创建相反的顺序创建的每个变量,并在这样做之前调用几个垃圾收集方法:

//garbage collector
GC.Collect();
GC.WaitForPendingFinalizers();

//cleanup
Marshal.ReleaseComObject(wsReport);
Marshal.ReleaseComObject(wSheetsReport);
Marshal.ReleaseComObject(wbReport);
Marshal.ReleaseComObject(workbooks);
Marshal.ReleaseComObject(excelApp);

使用这个方案我每次使用Excel已经解决了我的记忆问题,虽然它是乏味和可悲的,我们不能用链成员,我们已经习惯了的方式时间。



文章来源: C# Excel automation causes Excel memory leak