掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
ExcelをMarshal.ReleaseComObjectするタイミングは? (ID:146200)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
どこまでを解説するかで悩みますが、大原則として「必要」であると思っておいてください。 > VB2008で、Excelファイルの編集を行うプログラムを作成しています。 とりあえず、Excel 2007 + VB2008 の前提で回答しますね。 > 上記のようにプログラムの中でExcel.Applicationを終了させない場合でもReleaseComObjectは必要でしょうか? Excel.Application を Quit させず、そのまま残しておきたいわけですよね。 Quit させるかどうかに関わらず、その質問には『必要である』と答えておきます。 可能な限り、“自分が増やした参照カウント”は、自身で減ぜねばなりません。 その意味で、Marshal.ReleaseComObject は必ず呼び出さねばなりません。 以下は、Excel を Visible のまま残し、Quit せずにアプリを終了させるだけのアプリです。 終了タイミングを明確にするために、あえて WinForm ではなく、コンソールアプリとして書いてあります。 '【サンプルA】 Module Module1 Sub Main() Dim obj As Microsoft.Office.Interop.Excel.Application obj = New Microsoft.Office.Interop.Excel.ApplicationClass() obj.Visible = True Dim books As Microsoft.Office.Interop.Excel.Workbooks = obj.Workbooks Dim book As Microsoft.Office.Interop.Excel.Workbook book = books.Add() MsgBox("まだ Excel は残っているハズ。ReleaseComObject します。") System.Runtime.InteropServices.Marshal.ReleaseComObject(book) book = Nothing System.Runtime.InteropServices.Marshal.ReleaseComObject(books) books = Nothing System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) obj = Nothing MsgBox("ReleaseComObject しました。Excel は消えていますか?") End Sub End Module 上記が基本的な流れとなります。 2 回目のメッセージが表示された時点で、まだ Excel は表示されており、 アプリ終了後も、そのまま Excel は生き残り続けます。 もちろんユーザーが Excel を終了させれば、通常通り、EXCEL.EXE のプロセスも消失します。 なお上記にある Nothing の代入は、行っても行わなくても構いません。 なぜなら、今回使用した book/books/obj 変数は、いずれもメソッド内のローカル変数であるため、 End Sub に到達した時点で変数のスコープが外れるからです。しかし、フィールド変数の場合には、 できるだけ早期に解放される事を明示するために、Nothing を代入しておくことをお奨めします。 さて……以下は蛇足情報です。読み飛ばしてもらっても構いません。 Excel の場合、たとえ Quit していなくても終了してしまうケースがあります。 たとえば、ワークブックを読み込むことなく Excel.Application 単体を利用していた場合です。 '【サンプルB】 Module Module1 Sub Main() Dim obj As Microsoft.Office.Interop.Excel.Application obj = New Microsoft.Office.Interop.Excel.ApplicationClass() obj.Visible = True MsgBox("まだ Excel は残っているハズ。ReleaseComObject します。") System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) obj = Nothing MsgBox("ReleaseComObject しました。Excel は消えていますか?") End Sub End Module 先ほどとの違いは、ワークブックを Add / Open していないという点です。 この場合、2 回目のメッセージが表示された時点で、EXCEL.EXE のプロセスは終了します。 ただし、その Excel が他の場所で使われていた場合(VB.NET/VB6/VBScript 等で GetObject するなど)、 それらの参照が失われるまでの間、EXCEL.EXE のプロセスは終了せずに残り続けます。 (最後の参照が失われた場合、その時点で EXCEL.EXE も終了します) まぁ、今回は必ずブックを使うと思いますから、EXCEL.EXE のプロセスが消失する心配は 無いと思いますし、逆に EXCEL を終了させたいのであれば、Quit メソッドを呼ぶでしょうから、 あまり気にする必要は無いのかもしれませんけれどね。 さてもう一点。 ここで試しに、あえてサンプルBの ReleaseComObject の行を削ってみたとしましょう。 '【サンプルC】 Module Module1 Sub Main() Dim obj As Microsoft.Office.Interop.Excel.Application obj = New Microsoft.Office.Interop.Excel.ApplicationClass() obj.Visible = True MsgBox("まだ Excel は残っているハズ。ReleaseComObject します。") 'System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) 'obj = Nothing MsgBox("ReleaseComObject しました。Excel は消えていますか?") End Sub End Module 当然、2 回目のメッセージが表示された時点で、まだ Excel は表示されています。 しかし、アプリ終了後には、EXCEL.EXE のプロセスが消失するかと思います。 実は、COM オブジェクトがメモリから解放されたことを確認するメカニズムとしては、 ReleaseComObject メソッドとは別に、AppDomain オブジェクトという物があるのです。 AppDomain は、アンロード時に自身が増やした分の参照カウントを減ずる仕組みがあります。 また、COM オブジェクトが解放された後、RCW を解放してガベージ コレクションの対象にもできます。 ※ RCW : ランタイム呼び出し可能ラッパー (Runtime Callable Wrapper) たとえば、自分でアプリケーション ドメインを生成することもできます。 '【サンプルD】 Module Module1 Sub Main() Dim apd As AppDomain = AppDomain.CreateDomain("OratorDomain") Dim t As Type = GetType(Microsoft.Office.Interop.Excel.ApplicationClass) Dim obj As Microsoft.Office.Interop.Excel.Application obj = DirectCast(apd.CreateInstanceFromAndUnwrap(t.Assembly.Location, _ "Microsoft.Office.Interop.Excel.ApplicationClass"), _ Microsoft.Office.Interop.Excel.ApplicationClass) obj.Visible = True MsgBox("まだ Excel は残っているハズ。AppDomain を Unload します。") obj = Nothing '←忘れずに。 AppDomain.Unload(apd) MsgBox("AppDomain を Unload しました。Excel は消えていますか?") End Sub End Module この場合、2 回目のメッセージが表示された時点で、EXCEL.EXE のプロセスは消失しています。 つまり、ReleaseComObject を呼んでいないのに、サンプルBと同様の結果をもたらすという事です。 ただしこの場合、obj = Nothing の代入が必須である事に注意してください。 これを忘れると、AppDomain.Unload しても、そのオブジェクトは回収の対象となりません。 (ただしどちらにしても、End Sub の時点で、サンプルCと同様の理由により、EXCEL.EXE は消失します) なお、AppDomain の使用は実行コストの増加を招きますし、コード アクセス セキュリティ上の 問題も生じます。そのため、無闇に利用すべきものではありませんが、一応蛇足情報までに。 http://msdn.microsoft.com/ja-jp/library/aa159887.aspx
←解決時は質問者本人がここをチェックしてください。
更新する
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.