gpt4 book ai didi

c# - 在服务器端生成的 Excel 中获取 System.Runtime.InteropServices.COMException 错误

转载 作者:行者123 更新时间:2023-11-30 13:19:43 26 4
gpt4 key购买 nike

我们有一个网络应用程序可以生成 excel 电子表格并在服务器端运行宏。然后它通过电子邮件将它们发送给不同的人。它是旧报告样式的一部分,我们正在转换但仍支持我们作为 IIS 中的网站提供的新应用程序。

我知道执行 Office 自动化是一种不好的做法,因为我看到来自 Microsoft 的信息表明这不受支持。此处的答案中也指出了 opening excel error: 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 份报告时,它再次抛出错误。

更新:我们知道这是在自找麻烦,但我需要一个解决方案来解决问题。请记住,这是针对遗留内容的,我们将在未来停止支持这些内容,但在过渡期间,我们需要它发挥作用。

我们试过连载还是不行。我们尝试休眠生成 excel 报告的线程,当它遇到 COM 异常时,它可以工作,但这不是一个优雅的结果。解决此问题的任何好的解决方案都将获得赏金。

另一个更新:

通过在 finally block 上执行此操作解决

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 进程之前完全清除它。

最佳答案

Server execution failed

您没有展示太多研究,您应该经常查看 Windows 应用程序事件日志以获取有关此的更多详细信息。我假设您遇到了从 .NET 程序使用 Excel 的典型问题。

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

Excel 是一个“胖”进程,它使用许多操作系统资源。它实际上是为桌面使用而编写的,只有一个 Excel.exe 实例会运行。即使您再次启动它,第二个实例也会启动并注意到另一个实例已经在运行。它与第一个对话并要求它按照您的意思去做,比如打开另一个文档。并退出,只留下第一个运行。当您使用 COM 时,同样的机制到位。如果您只创建一个实例并让它完成所有工作,您就必须亲自处理它。

这些 Excel.exe 实例在您停止使用时不会退出是有充分理由的。您的程序中存在垃圾回收问题。收集器运行不够频繁。很容易陷入这种麻烦,您通常会让 Excel 完成所有繁重的工作,而您自己从来没有分配足够的对象来让垃圾收集器运行。

这很麻烦,Excel 只有在其接口(interface)实例被垃圾回收时才能退出。内存管理在 COM 互操作场景中非常不同,它是引用计数的。当你开始使用一个接口(interface),比如应用程序,那么引用计数就会增加。当终结器运行时它会下降。在垃圾收集之后才会发生这种情况。

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

执行此操作的最佳方法是在使用完 Excel 后强制触发垃圾回收。将任何接口(interface)引用设置为 null 并调用 GC.Collect() + GC.WaitForPendingFinalizers()。一定要在没有附加调试器的情况下为发布版本测试它。并确保使用与使用 Excel 界面的方法不同的方法来执行此操作。任务管理器会告诉您是否领先。

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

关于c# - 在服务器端生成的 Excel 中获取 System.Runtime.InteropServices.COMException 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16329581/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com