Excel スプレッドシートを生成し、サーバー側でマクロを実行する Web アプリケーションがあります。その後、それらを電子メールで別の個人に送信します。これは移行中の従来のレポート スタイルの一部ですが、IIS で Web サイトとして配信した新しいアプリケーションで引き続きサポートされています。
Microsoft から Office Automation がサポートされていないという情報を見たので、Office Automation を実行するのが悪い習慣であることはわかっています。これは、Excel のエラーを開く回答にも示されています: 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()
何が間違っている可能性がありますか? 最初のレポートは成功しましたが、再実行するとすべての失敗したレポートが正常に続行され、15 から 20 番目のレポートが生成されると再びエラーがスローされるため、Excel テンプレートではないことがわかります。
更新: 問題が発生したことは承知していますが、問題を解決するための解決策が必要です。これは、将来的にサポートを停止するレガシーのものであることを忘れないでください。ただし、移行期間には機能する必要があります。
シリアル化を試みましたが、まだ機能しません。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 プロセスを完全にクリアします。