ご存知のとおり、.net の世界では、プログラマは new を使用してオブジェクトを作成することのみを担当し、オブジェクトの破棄はガベージ コレクションが発生した場合にのみ完全に任されます。.net 内の型は破棄されます。通常、これによって問題は発生しません。ただし、アンマネージド COM オブジェクトを使用する場合には、特別な問題が発生します。
COM は、参照カウントを使用してオブジェクトの存続期間を決定します。COM クライアントはオブジェクトを参照するたびに呼び出します。
IUnKnown->AddRef()、オブジェクトが解放されるたびに呼び出されます
IUnKnown->Release() は、参照カウントが 0 に達するとインスタンスを解放します。
問題が発生したので、次のコードを見てみましょう。
これは、Excel com コンポーネントを使用して Excel ファイルをクライアントにエクスポートする C# コードであり、CSDN の asp.net バージョンで広く流通しています。このコードを追加する前に、com 参照を追加するためのウィザードが実行されました。
Excel.アプリケーション oExcel;
Excel.Workbook oBook;
オブジェクト oMissing = System.Reflection.Missing.Value;
oExcel = 新しい Excel.Application();
oBook = oExcel.Workbooks.Add(oMissing);
for (int i=1;i <=4;i++)
{
oExcel.Cells[i,1]=i.ToString();
oExcel.Cells[i,2]= "'bbb2 ";
oExcel.Cells[i,3]= "'ccc3 ";
oExcel.Cells[i,4]= "'aaa4 ";
}
oBook.Saved = true;
oExcel.UserControl = false;
文字列ファイル名 = DateTime.Now.Ticks.ToString();
string mm=Server.MapPath( ".")+ "\" + ファイル名 + ".xls";//サーバーストレージアドレス
oExcel.ActiveWorkbook.SaveCopyAs (mm);
oExcel.Quit();
//GC.Collect();
Response.Redirect(ファイル名+".xls");
このコードでファイルのエクスポート機能を実現できるのですが、Windowsのタスクマネージャーを見ると以下のような素晴らしいシーンが見つかります。
そこで、誰かがコードに「GC.Collect();」を追加しました。以下に示すように、EXCEL.EXE の数はそれほど多くありません。
しかし、どうすれば完全な解放を達成できるのでしょうか?
幸いなことに、.net では、プログラマ自身が com の Release メソッドを明示的に呼び出すことができます。このメソッドは .net によってパッケージ化されており、上記のコードでは System.Runtime.InteropServices.Marshal.ReleaseComObject と呼ばれています。
「GC.Collect();」を呼び出す前に、まず「System.Runtime.InteropServices.Marshal.ReleaseComObject((object)oExcel);」を呼び出します。
参照カウントを 1 つ減らすと、参照カウントが 0 になります。ガベージ コレクションが発生すると、oExcel に対応する COM オブジェクトが掃き出されます。