質問:
この質問に対する Mike Rosenblum の回答に対して質問したいです。質問は、Excel 相互運用オブジェクトのクリーンアップに関するものでした。提案されたいくつかの解決策 (たとえば、ラッパー、複数のドットを使用しない、Excel プロセスを強制終了する) が、私はこの問題に対する Mike Rosenblum の解決策が最も気に入りました (このトピックに関する長い記事)。
それが基本的に言っていることは、周りに浮かんでいるすべての参照についてあまり心配しないということです. いくつかの主要なもの(ApplicationClass
、Workbook
および などWorksheet
)を保持するだけです。最初にガベージ コレクションを呼び出して、浮遊しているすべてのオブジェクトをクリーンアップし、次にMarshal.FinalReleaseComObject
(重要度の逆順で) 呼び出して、まだ残っているメイン参照を明示的にクリーンアップします。
これについて 2 つの質問があります。
最初に: どのオブジェクトへの参照を保持する必要があるかを判断するにはどうすればよいですか? Mike Rosenblum の例ではRanges
、 、Worksheets
、Workbooks
およびのみを保持してApplicationClasses
います。
2 番目: オブジェクトが他にもある場合、それらをクリーンアップする順序 (つまり、「重要な順序」) を決定するにはどうすればよいですか?
前もって感謝します。
更新 1:
MattC
注文に関して重要なのは、アプリが最後にリリースされることだけであることが示唆されています。ただし、私の参考文献では次の文があります。より多くの順序があることを意味します。
nobugz
すべてを に設定してからnull
ガベージ コレクションを実行するだけで十分であることが示唆されていますが、それは Mike Rosenblum の記事からの次の引用と矛盾しているように思われます。ただし、Microsoft Office アプリケーションは、オブジェクトが解放される順序に敏感であり、残念ながら、変数 =を設定して呼び出しても、オブジェクトの解放順序は保証されません。Nothing
GC.Collect()
Nothing
GC.Collect()
更新 2:
追加情報: 私自身のアプリケーションでは、チャートを使って多くのことを行います。プロパティなどをいろいろ設定しています。 なるほど、新しいCOMオブジェクトを作るところが多いですね。ダブル ドットを使用しないように注意し、Marshal.FinalReleaseComObject
終了したすべてのオブジェクトを呼び出すようにしました。多くのネスティングが発生するため、ラッパー アプローチは使用しませんでした。
EXCEL.exe
アプリが作業を終了した後、閉じませんでした。しかし...同じ作業をもう一度行うようにアプリに指示したところ、閉じました。もちろん、EXCEL.exe
閉じなかった新しいオープン。今、すべてのMarshal.FinalReleaseComObject
呼び出しを削除しましたが、アプリはまったく同じように動作します。EXCEL.exe
アプリに作業をやり直すように指示するまで、滞在しますが、その後、新しい開始EXCEL.exe
と滞在が続きます。
編集:また、COM以外の他の作業を行うようにアプリに指示すると、しばらくするとEXCEL.exe
消えますが、新しいものEXCEL.exe
は表示されません。
ここから導き出せる結論はわかりません...