在服务器端生成的Excel中出现System.Runtime.InteropServices.COMException错

本文关键字:System Runtime InteropServices COMException 服务器端 Excel | 更新日期: 2023-09-27 18:11:40

我们有一个web应用程序,它生成excel电子表格并在服务器端运行宏。然后通过电子邮件发送给不同的人。它是传统报表风格的一部分,我们正在过渡,但仍然支持我们的新应用程序,我们在IIS中作为网站交付。

我知道这是一个不好的做法做办公自动化,因为我从微软看到的信息,这是不支持的。System.Runtime.InteropServices.COMException (0x80080005):为具有CLSID的组件检索COM类工厂

总之,为了缩短故事,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之前完全清除excel进程。

在服务器端生成的Excel中出现System.Runtime.InteropServices.COMException错

服务器执行失败

你没有显示太多的研究,你应该总是看看Windows应用程序的事件日志,以获得更多的细节。我就假设你遇到了在。net程序中使用Excel的典型问题。

这个错误描述总是准确的,COM可以不启动Excel.exe。这几乎总是因为操作耗尽了资源,内核内存池通常是耗尽的那个。您通常可以通过启动任务管理器(希望它仍然有效)并查看Processes选项卡来了解原因。很有可能你会看到几十个Excel.exe副本在运行。如果你无法启动任务管理器,那么当你重新启动应用程序时,请密切关注列表。

Excel是一个"胖"进程,它使用许多操作系统资源。它实际上是为桌面使用而编写的,只有一个Excel.exe实例会运行。即使您再次启动它,第二个实例也会启动并注意到另一个实例已经在运行。它与第一个程序对话,并要求它做你想让它做的事情,比如打开另一个文档。他退出了,只剩下了第一场比赛。当您使用COM时,同样的机制是而不是。如果你只创建一个实例,并让它完成所有的工作,你就可以自己照顾它。

有一个很好的理由为什么这些Excel.exe实例不退出当你停止使用它们。程序中的垃圾收集有问题。收集器不经常运行。很容易陷入这种麻烦,你通常会让Excel做所有繁重的工作,而你自己从来没有分配足够的对象来运行垃圾收集器。

这意味着麻烦,Excel只能退出当它的接口实例被垃圾收集。内存管理在COM互操作场景中是非常不同的,它是引用计数的。当您开始使用一个接口(如Application)时,引用计数就会增加。当终结器运行时它会下降。在垃圾回收之后才会发生。

许多程序员通过调用Marshal.ReleaseComObject()来强制减少引用计数来解决这个问题。许多程序员也会因此遇到麻烦,除非您为每个接口引用调用它,否则它将无法工作。是否有一些在程序中是不可见的

最好的方法是在你使用完Excel后强制触发垃圾收集。将任何接口引用设置为null并调用GC.Collect() + gc . waitforpendingfinalizer()。请确保在没有附加调试器的情况下对发布版本进行测试。而且一定要在一个与使用Excel接口的方法分开的方法中做。任务管理器告诉你是否你在前面。

在服务器上运行Excel仍然是一个坏主意,但如果这种方法适合你,那么你将有一些喘息的空间。

我遇到过一个类似的问题。上面的答案似乎是正确的——你可能实际上有一个未垃圾收集的excel实例池阻塞了服务器。

我的解决方案是非常小心地打开-创建-关闭每个excel实例作为一个工作单元,然后检查是否有任何excel实例留在服务器进程上。它只是在晚上一个接一个地检查它们,然后把它们放在一个储存库中,第二天早上发出去。

我们尝试过的另一个想法是创建CSV文件而不是excel文件,但最终没有使用。如果您只需要数据,那么CSV要轻量级得多。我们在工作簿中也有复杂的公式,没有这些公式就无法完成。

你真是在自找麻烦。看看这是否有帮助:http://blogs.msdn.com/b/adioltean/archive/2005/06/24/432519.aspx

您可以通过使用ASP使用异步编程实现您的解决方案。. NET、MSMQ和Windows Service,用于长时间运行的进程,如报表生成

基于web的架构需要持续的进程/线程执行,这就是为什么当具有生成大量报告的报告功能时经常发生系统故障的原因。

看看下面这篇文章,我希望它对你有用。

http://www.codeproject.com/Articles/8809/How-to-do-asynchronous-programming-using-ASP-NET-M

的问候shaz

相关文章: