COM Interop を使用して Microsoft Office アプリケーションに接続する WinForms アプリケーションがあります。COM オブジェクトを適切に破棄する方法に関する多くの資料を読みました。これは、Microsoft 自身の記事 ( here )の手法を使用したアプリケーションの典型的なコードです。
Excel.Application excel = new Excel.Application();
Excel.Workbook book = excel.Workbooks.Add();
Excel.Range range = null;
foreach (Excel.Worksheet sheet in book.Sheets)
{
range = sheet.Range["A2:Z2"];
// Process [range] here.
range.MergeCells();
System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
range = null;
}
// Release explicitly declared objects in hierarchical order.
System.Runtime.InteropServices.Marshal.ReleaseComObject(book);
System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
book = null;
excel = null;
// As taken from:
// http://msdn.microsoft.com/en-us/library/aa679807(v=office.11).aspx.
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
この質問のコードをより明確にするために、すべての例外処理が取り除かれています。
ループ内の[sheet]
オブジェクトはどうなりますか? [foreach]
おそらく、それはクリーンアップされず、列挙中に改ざんすることもできません。代替手段の 1 つは、インデックス作成ループを使用することですが、これは見苦しいコードになり、Office オブジェクト ライブラリの一部の構成体はインデックス作成をサポートしていません。
また、[foreach]
ループはコレクションを参照します[book.Sheets]
。孤立した RCW カウントも残りますか?
ここで2つの質問:
- 列挙が必要な場合にクリーンアップするための最良の方法は何ですか?
- のような中間オブジェクトは、明示的に宣言またはクリーンアップされていないため、どうなりますか
[Sheets]
?[book.Sheets]
アップデート:
私は Hans Passant の提案に驚き、何らかの文脈を提供する必要があると感じました。
これは、クライアントが Access、Excel、Outlook、PowerPoint、Word などのさまざまな Office アプリに接続するクライアント/サーバー アプリケーションです。エンドユーザーによって実行される特定のタスクをテストし、トレーニング モードでそれらをシミュレートする 1,500 を超えるクラス (および増加中) があります。これは、アカデミック環境での Office 習熟度について学生をトレーニングおよびテストするために使用されます。複数の開発者と大量のクラスがあるため、COM フレンドリーなコーディング プラクティスを適用することは困難でした。最終的には、リフレクションとソース コードの解析を組み合わせて自動テストを作成し、コード レビュー前の段階でこれらのクラスの整合性を確保することにしました。
ハンスの提案を試して元に戻します。