这在COM API Word加载项中。是的,通常是Hans Passant's advice to let .NET clean everything up works。
但是在以下情况下它不起作用-我已经测试了运行正常(没有调试器),并将其范围缩小到了以下特定代码:
private Chart chart;
private bool displayAlerts;
private Application xlApp;
Chart chart = myShape.Chart;
ChartData chartData = chart.ChartData;
chartData.Activate();
WorkbookData = (Workbook)chartData.Workbook;
xlApp = WorkbookData.Application;
displayAlerts = xlApp.DisplayAlerts;
xlApp.Visible = false;
xlApp.DisplayAlerts = false;
WorksheetData = (Worksheet)WorkbookData.Worksheets[1];
WorksheetDataName = WorksheetData.Name;
WorksheetData.UsedRange.Clear();
// ... do a bunch of stuff including writing to the worksheet
xlApp.DisplayAlerts = displayAlerts;
WorkbookData.Close(true);
我认为问题很可能是Word向我提供了此工作簿,因此谁知道它在实例化Excel方面在做什么。但是即使退出Word,Excel实例仍在运行。
同样,在Word(不是Excel)中,访问图表对象以更新图表中的数据。
答案 0 :(得分:1)
COM对象需要完全释放,否则“孤立”对象可以将应用程序保留在内存中,即使调用它的代码超出了范围。
由于使用了xlApp
,因此这种特殊情况可能会很特殊(与您之前使用的其他代码相比)。默认情况下,使用Office 2007中引入的对象模型来操纵图表时(我认为是),不需要或不使用Excel Application
对象。在问题代码中使用它来隐藏Excel窗口,该窗口在默认情况下(根据设计)是可见的。但是对象模型的设计目的不是要清理它-假定它不存在...
在我的测试中,对象(在引用问题中的代码时)正确释放:
所有Excel对象都以实例化的相反顺序设置为null
,请确保先退出 Excel应用程序,然后再尝试将其设置为null
:
WorksheetData = null;
WorkbookData = null;
xlApp.Quit();
xlApp = null;
然后,当使用COM点符号时,C#倾向于在幕后创建对象-这些对象并非总是会被正确清理(发布)。因此,最好为正在使用的层次结构的每个级别创建一个对象。 (注意:VBA不会出现此问题,因此需要重新处理从VBA示例或宏记录器中拾取的任何代码。)从问题中的代码影响WorksheetData.UsedRange.Clear();
>
Excel.Range usedRng = WorksheetData.UsedRange;
usedRng.Clear();
usedRng = null;
进行标准清理,以确保在可预见的时刻释放所有内容:
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
当出现这种情况时,我总是引用Andrew Whitechapel撰写的“ .NET Development for Office”。考虑到多年来对C#的更改,这确实是“裸露的骨头”,并且其中的某些不再有用(以VB.NET“更容易”的方式使其“更易于使用”)。但是,COM与.NET交互的方式一直没有改变,从深层次...