use*_*649 12 c# com excel automation interop
我正在尝试将C#与COM Interop库一起使用来打开一组非常繁重的Excel工作簿.我必须使用C#,因为我还需要启动宏,移动一些单元格,并启动我公司使用的自定义excel-add-in.
然后我的程序退出,打开工作簿,每个工作簿都在一个单独的excel实例中.我不希望在程序退出时关闭工作簿.
问题是当我的C#程序退出时,随着时间的推移,excel工作簿逐渐消耗更多的内存,直到他们从原来的500 MB消耗3.5 GB的内存.
我曾经手工打开工作簿,这些工作表从来没有消耗过那么多的记忆.一旦我开始使用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;
Run Code Online (Sandbox Code Playgroud)
我读到了你需要如何使用Marshal来释放用途,所以我现在正在尝试以下代码,但没有简单的方法来测试它,除了打开所有工作表并查看它们是否消耗了太多数据.
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;
Run Code Online (Sandbox Code Playgroud)
And*_*atz 17
使用MS Office COM Interop库时,我遇到了一些避免内存泄漏的事情:
首先,"不要使用两个点"是记住它的最佳方式,但基本上,总是为新变量分配一个新的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");
Run Code Online (Sandbox Code Playgroud)
其次,调用Marshal.ReleaseComObject()
以创建的相反顺序创建的每个变量,并在执行此操作之前调用几个垃圾收集方法:
//garbage collector
GC.Collect();
GC.WaitForPendingFinalizers();
//cleanup
Marshal.ReleaseComObject(wsReport);
Marshal.ReleaseComObject(wSheetsReport);
Marshal.ReleaseComObject(wbReport);
Marshal.ReleaseComObject(workbooks);
Marshal.ReleaseComObject(excelApp);
Run Code Online (Sandbox Code Playgroud)
每次使用Excel时都使用这个方案已经解决了我的记忆问题,虽然它很乏味和悲伤,我们不能像我们习惯的那样使用链式成员.
归档时间: |
|
查看次数: |
5896 次 |
最近记录: |