完成后如何关闭Excel?

时间:2018-12-31 02:27:41

标签: ms-word office-interop excel-interop

这在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)中,访问图表对象以更新图表中的数据。

1 个答案:

答案 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交互的方式一直没有改变,从深层次...