【发布时间】:2019-05-28 18:45:28
【问题描述】:
我有一个 c# 程序,它打开一个 excel 工作表,用一些数据填充它,并在关闭工作表之前从工作表中检索一些信息。这在循环内发生了好几次。程序执行了一段时间来完成循环,然后在循环期间随机失败,并出现以下错误:
System.Runtime.InteropServices.COMException (0x80080005):正在检索 CLSID {xxx} 的组件的 COM 类因子失败,原因是 以下错误:80080005 服务器执行失败 [异常来自 HRESULT:0x80080005 (CO_E_SERVER_EXCEC_FAILURE))。
我已经检查了我对 Microsoft.Office.Interop.Excel 的参考,它是 Microsoft Excel 16.0 对象库版本 1.9.0.0,并且我安装了 Excel 2016。导致问题的代码类似于以下内容:
for (int i = 0; i < 100; i++)
{
Excel.Application xlApp;
Excel.Workbooks xlWorkBooks;
Excel.Workbook xlWorkBook;
Excel.Sheets xlWorksheets;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlApp = new Excel.Application(); //line that causes error
xlApp.Visible = false;
xlApp.ScreenUpdating = false;
xlWorkBooks = xlApp.Workbooks;
xlWorkBook = xlWorkBooks.Open(IIHSTemplate.Text, 0, false, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
xlWorksheets = xlWorkBook.Worksheets;
xlWorkSheet = xlWorksheets["Automatic-Data-Analysis"];
IIHSDemerit = Convert.ToDouble((xlWorkSheet.Cells[30, 14] as Excel.Range).Value2);
xlWorkBook.Close(false, misValue, misValue);
xlApp.Quit();
releaseObject(xlWorksheets);
releaseObject(xlWorkSheet);
releaseObject(xlWorkBooks);
releaseObject(xlWorkBook);
releaseObject(xlApp);
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Exception Occured while releasing object " + ex.ToString());
}
finally
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
我的程序将 excel 数据的结果写入一个文本文件并执行多次,没有错误。经过随机次数的迭代(每次运行程序时数字不同),程序将失败并出现上面列出的错误。关于导致错误的原因以及如何纠正错误的任何想法?
【问题讨论】:
-
是否有理由在循环内创建和发布 Excel 应用程序?当您只是打开和关闭工作簿时,这似乎没有必要。这可能是一个促成因素,因为系统正试图非常快速地启动和停止 Excel 的副本。
-
传统错误,那些 releaseObject() 调用没有任何用处。使用任务管理器的进程选项卡查看您创建的大量 Excel.exe 实例。这确实在某处停止,Excel 是一个非常昂贵的过程。只需启动一次并 correctly releasing it 即可获得成功。注销并重新登录以快速从流程爆炸中恢复。
-
@Hans Passant - 我检查了任务管理器,每次运行 Microsoft Excel (32) 位进程都会启动和停止。没有Excel.exe进程的积累。
-
@SmrtGrunt - 感谢您的建议。之前没有注意到,但是在阅读您的评论并考虑之后,这很明显。现在就试试吧。