我们有一个 Web 应用程序,可以生成 Excel 电子表格并在服务器端运行宏。然后它通过电子邮件将它们发送给不同的人。它是我们正在过渡但仍支持我们作为 IIS 中的网站交付的新应用程序的旧报告样式的一部分。
我知道执行 Office 自动化是一种不好的做法,因为我从 Microsoft 看到了不支持此功能的信息。此处的答案中也指出了打开 excel 错误: System.Runtime.InteropServices.COMException (0x80080005): Retrieving the COM class factory for component with CLSID
无论如何,为了简短起见,excel 报告是在批处理场景中生成的,可以生成 3 到 300 个发送给不同人的报告。报告生成工作正常,直到它达到第 15 到第 20 个项目然后它就崩溃了,它给了我下面的错误
System.Runtime.InteropServices.COMException (0x80080005): Retrieving the COM class factory for component with CLSID {00024500-0000-0000-C000-000000000046} failed due to the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).
at System.Runtime.Remoting.RemotingServices.AllocateUninitializedObject(RuntimeType objectType)
at System.Runtime.Remoting.Activation.ActivationServices.CreateInstance(RuntimeType serverType)
at System.Runtime.Remoting.Activation.ActivationServices.IsCurrentContextOK(RuntimeType serverType, Object[] props, Boolean bNewObj)
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at Ci.Infrastructure.Reporting.ReportProviderExcel.RunReport()
可能有什么问题?第一份报告成功了,我知道它不是 excel 模板,因为当我再次重新运行它时,所有失败的报告都会成功继续,当生成第 15 到第 20 份报告时,它会再次抛出错误。
更新:我们知道是在自找麻烦,但我需要一个解决方案来解决这个问题。请记住,这是针对我们将来会停止支持的遗留内容,但在过渡期间我们需要它工作。
我们尝试了序列化仍然不起作用。我们尝试在遇到 COM 异常时使生成 excel 报告的线程休眠,它可以工作,但这不是一个优雅的结果。任何解决此问题的好的解决方案都将获得赏金。
另一个更新:
通过在 finally 块上执行此操作解决
finally
{
if (dataWorksheet != null)
{
Marshal.ReleaseComObject(dataWorksheet);
}
if (worksheets != null)
{
Marshal.ReleaseComObject(worksheets);
}
if (workbook != null)
{
workbook.Close(false);
Marshal.ReleaseComObject(workbook);
}
if (workbooks != null)
{
workbooks.Close();
Marshal.ReleaseComObject(workbooks);
}
if (excel != null)
{
excel.Quit();
Marshal.ReleaseComObject(excel);
}
}
就像 MarkWalls 所说的那样,关闭每个 excel 实例作为一个工作单元,在再次使用之前完全清除 EXCEL 进程。