2012-02-13 43 views
5

これは前に説明したことは分かっていますが、満足のいく答えが見つかりませんでした。C#でCOMオブジェクトを解放します

私は以下のように開いて、ディスプレイを呼び出している電子メールファイル(.msg)を持っています。

oApp = new Microsoft.Office.Interop.Outlook.Application(); 
mail = (Microsoft.Office.Interop.Outlook.MailItem)oApp.Session.OpenSharedItem(fileName); 
mail.Display(false); 
oApp = null; // do I need to release this object ? 

ユーザはそれを閉じて再度開くことができます。彼らが "再オープン"をクリックする前に、私はウィンドウがまだ存在するかどうかをチェックし、そうであればそのウィンドウにSetForeground(hwnd)を送信します。そうでなければ、それはユーザーがそれを閉じたことを意味するので、mailItemオブジェクトを解放して再び開くだけです。

public static void ReleaseCOMObject(Microsoft.Office.Interop.Outlook.MailItem item) { 
     int r = System.Runtime.InteropServices.Marshal.ReleaseComObject(item); 
     while (r != 0) { 
      r = System.Runtime.InteropServices.Marshal.ReleaseComObject(item); 
     } 
    } 

再度同じファイルを開こうとするとそれは "時々" "使用中のファイルの例外"をスローするので、私はMailItemをリリースしているにもかかわらず、それは適切にリリースされていないと思う。

リリースが適切に行われるようにするにはどうすればよいですか。ファイルのクローズと再オープンは非常に一般的なシナリオです。

すべてのポインタは非常に役に立ちます。

+1

参照カウンターをインクリメントするときに "解放"し、他の参照を解放すると問題が発生することがあります。 – Matthew

答えて

6

.NETのCOM-interop機能を使用している場合は、これについて心配する必要はありません。

COMは参照カウントを追跡し、参照カウントが0になるとCOMオブジェクトが自動的に解放され、.NETは標準のCOM参照カウントメカニズムを使用して処理します。

CのライブラリにP/Invokingしていた場合、状況は異なる可能性がありますが、あなたのような標準的な状況で心配する必要はありません。このようなことをやって

+0

私が間違っていることがわかりません。私は "File In use Exception"を取得すると、自分の見通しを再開することがそのトリックを行うことに気付きました。 "oApp = new Microsoft.Office.Interop.Outlook.Application();"のために必要なクリーンアップの種類? – karephul

+2

その作業中 - > MailItemを保持していて、それを解放していない別のモジュールがありました。 – karephul

+0

ところで、ちょうど "ReleaseCOMObject"を働かせなければならなかったことを伝えたいと思っています。 – karephul

3

mail = (Microsoft.Office.Interop.Outlook.MailItem)oApp.Session.OpenSharedItem(fileName); 

は、子オブジェクトへの参照が適切に処分されていませんので、あなたはからReleaseComObjectを呼び出す場合でも捨てないへの参照が発生します。

session = oApp.Session; 
mail = (Microsoft.Office.Interop.Outlook.MailItem)session.OpenSharedItem(fileName); 

をそして、あなたは、順番に、セッションのように、これらのサブオブジェクトのそれぞれを処分する必要があります

あなたはこのような呼び出しを行う必要があります。

+0

私のマシンでOutlookが実行されていないと気付きました。閉鎖と再開私が以前に説明した方法)うまく動作します。私はいくつかの見通しがそのファイルへの参照を保持していると思います。そこにどんなポインタ?セッションオブジェクトを個別に解放しようとしました。(作業しないでください) – karephul

+0

マーシャルに電話していますか?あなたがメールアイテムを取得しているのと同じメソッド内のReleaseComObjectメソッド、またはoncloseイベントハンドラなどでそれをやっていますか? – Nanhydrin

+0

メールアイテムを開く前に、同じタイトルのウィンドウがあるかどうかを確認します。それ以外の場合は、ReleaseComObject(mailItem)..を開き、もう一度開きます。 [ユーザーは電子メールウィンドウを閉じた可能性があります]。基本的には、できる限り私はMailItemを保持していますので、定期的に保存することができます。 – karephul

関連する問題