【问题标题】:C# EXCEL Interop Issues. Cleanup doesn't workC# EXCEL 互操作问题。清理不起作用
【发布时间】:2015-05-04 07:35:12
【问题描述】:

我在堆栈和其他网站上阅读了很多不同的主题和文章,但是当我完成我的应用程序时,我在清理 EXCEL 互操作 COM 进程时仍然遇到一些问题。

我自己创建了一个小类,它允许我加载工作表、修改单元格、重命名工作表以及格式化不同的单元格。

这是我正在使用的变量和构造函数。

Excel.Application _excelApp = null;
Excel.Workbook _excelBook = null;
Excel.Worksheet _excelSheet = null;
Excel.Range _excelRange = null;

当我创建我的类对象时,构造函数会这样做:

FileName = excelFileName; // Just used to reference a creation name
_excelApp = new Excel.Application();

现在,我要做的下一件事是加载一张表格进行修改:

 public bool LoadExcelSheet(string location, string file)
 {
      string startupPath = Environment.CurrentDirectory; // Get the path where the software is held

      _excelBook = _excelApp.Workbooks.Open(Path.Combine(startupPath, location, file)); // Load in the workbook

      _excelSheet = _excelBook.Worksheets[1]; // sets the excel sheet to the init worksheet

      sheetName = _excelSheet.Name; // set the sheetname variable

      isSheetLoaded = CheckIfWorkBookExists(); // a little check to see if the workbook exists - yes shows it has been loaded, if a no then it hasn't

      return isSheetLoaded;

}

我在我的软件中做的下一件事是通过一个函数运行,该函数允许我设置任何单元格(通过定义行和列的 int ID)并使用给定的字符串修改它:

public void ModifyCell(int row, int column, string data)
{
     int[] cellRange = new int[2] { row, column };

     _excelRange = _excelSheet.Cells;
     _excelRange.set_Item(row, column, data);

     dataFormat.Add(cellRange); // this adds each row and column into a list which holds every modified cell for easy formatting

     Marshal.ReleaseComObject(_excelRange); // Releases the COM object
}

所以,当我完成我的 excel 操作时,我会调用我的清理函数:

public void Cleanup()
{
    if (_excelApp != null) // if a cleanup hasn't been initiated
    {
                    // set all the com objects to null, this is so the GC can clean them up
                    _excelRange = null;
                    _excelSheet = null;
                    _excelBook = null;
                    _excelApp = null;
                }

                // These garbage collectors will free any unused memory - more specifically the EXCEL.EXE*32 process that LOVES to stay, forever and ever. Like a mother inlaw...
                GC.GetTotalMemory(false);
                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
                GC.GetTotalMemory(true);  
    }
}

我在完成对 Excel 表的修改时运行清理,并且当我关闭程序只是为了仔细检查所有内容是否已清理时。不过,那个该死的EXCEL.EXE*32 仍然存在!

【问题讨论】:

  • IIRC,工作簿应该是closed
  • 我不确定它是否仍然是真的,但我认为它是......你根本不能指望托管代码端通过调用类似于你的清理方法的东西来清理 COM 端对象.转到 CodeProject 或 Stackoverflow 并查找“使用 Dispose 的正确方法”或“IDispose”......这是我无法忍受在 MSFT 平台上使用 Interop 类的原因之一......它表明了疏忽MSFT 不愿意让 COM 和托管端保持无缝。
  • @chris 谢谢,那行得通。完成后我也关闭了应用程序。不敢相信我错过了。
  • @JohnPeters 什么是 MSFT?
  • 啊,对...啊哈尴尬。

标签: c# excel com


【解决方案1】:

使用 Excel(实际上是任何 Office 应用程序)互操作,您在管理资源时必须非常勤奋。您应该始终尽可能短地使用资源,并在不再需要它们时立即释放它们。您还应该明确释放所有对象以确保它们被正确清理。

这是我的一个更详细的旧答案:COM object excel interop clean up

如果您按照答案中列出的步骤进行操作,您将不会有多余的 Excel 实例。

【讨论】:

  • 感谢 xxbbcc 的回答。我还关注了克里斯的评论,该评论停止了流浪过程。
  • 给出了很棒的答案,我确实喜欢学习新事物!我将改变我使用 COM 对象的方式,并尝试准确了解您的 COM Wrapper 的功能!再次感谢。
  • @JohnathanBrown 谢谢 - 我很高兴它有用。
猜你喜欢
  • 2017-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多