C#中的Hung Excel进程

时间:2015-07-23 02:50:51

标签: c# excel

我有一个C#程序,它打开一个Excel文件,读取一个单元格,关闭文件,然后退出Excel。不幸的是,Windows任务管理器仍然显示正在运行的Excel.exe进程。我已经阅读了关于这个问题的每篇文章,并尝试了几乎所有的解决方案。 。 。并仍然有同样的问题。我相信其中一个COM对象没有被释放,从而挂起了这个过程。但是,我也相信我一直非常小心地实例化Excel对象(没有双“。”)并释放它们。

如果我删除“a = xlCells [1,1] .Value”行,那么每个东西都会释放,Excel会在Application实例的FinalReleaseComObject之后干净地死掉。为什么这个赋值会创建COM对象或干扰它们?

        Excel.Application xlApp = null;
        Excel.Workbooks xlWorkbooks = null;
        Excel.Workbook xlWorkbook = null;
        Excel.Sheets xlSheets = null;
        Excel.Worksheet xlWorksheet = null;
        Excel.Range xlCells = null;

        string inputFile = @"C:\Temp\test.xlsx";
        string a;

        xlApp = new Excel.Application();
        xlApp.Visible = false;
        xlApp.DisplayAlerts = false;
        xlWorkbooks = xlApp.Workbooks;
        xlWorkbook = xlWorkbooks.Open(inputFile);
        xlSheets = xlWorkbook.Sheets;
        xlWorksheet = xlSheets[1];
        xlCells = xlWorksheet.Cells;

        a = xlCells[1,1].Value;

        Marshal.FinalReleaseComObject(xlCells);
        xlCells = null;

        Marshal.FinalReleaseComObject(xlWorksheet);
        xlWorksheet = null;
        Marshal.FinalReleaseComObject(xlSheets);
        xlSheets = null;      
        xlWorkbook.Close(false, Type.Missing, Type.Missing);
        Marshal.FinalReleaseComObject(xlWorkbook);
        xlWorkbook = null;
        xlWorkbooks.Close();
        Marshal.FinalReleaseComObject(xlWorkbooks);
        xlWorkbooks = null;

        xlApp.Quit();
        Marshal.FinalReleaseComObject(xlApp);
        xlApp = null;

2 个答案:

答案 0 :(得分:0)

我会做两处修改。首先,由于Sheets项目可以是工作表或图表工作表,因此最好使用As进行投射并检查null。其次,如果您只想获得带有字母数字地址的范围,get_Range()方法效果很好。否则,如果您想按行和列索引进行操作,请按照@Daneau的评论进行操作。

xlWorksheet = xlSheets[1] as Excel.Worksheet;
if(xlWorksheet != null)
{
    xlCells = xlWorksheet.get_Range("A1");
    a = xlCells[1,1].Value;

    Marshal.FinalReleaseComObject(xlCells);
    xlCells = null;

    Marshal.FinalReleaseComObject(xlWorksheet);
    xlWorksheet = null;
}

答案 1 :(得分:0)

我更改了代码并添加了虚拟Range对象。

Range tmpCell = xlCell[1,1];
a = tmpCell.Value;
Marshal.ReleaseComObject(tmpCell);

我的问题消失了。非常感谢,Daneau!

真正的例程有几个循环,正在评估单元格。我认为使用tmpCell为每个新的单元格赋值都可以正常工作,然后在最后发布tmpCell。那失败了。在每个新的tmpCell赋值给xlCell [x,y]之前,我不得不释放tmpCell。这有效,但肯定很麻烦。很难相信没有更好的方法来管理它或跟踪各种COM对象。