Release COM Object in C#

2019-02-13 23:20发布

I know this has been discussed earlier but I couldn't find a satisfactory answer.

I have an e-mail file (.msg) which I open like below and then call Display.

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 ?

users can close it and re-open it. Before they click "reopen" I check to see if the window still exists, if yes .. then just send a SetForeground(hwnd) to that window. if Not, that means user closed it so just release the mailItem object and open again.

 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);
        }
    }

If I try to open the same file again. It "sometimes" throws a "file in use exception" So, I think even though I am releasing the MailItem .. its not been released properly.

What can I do to ensure that its released properly. closing and reopening a file is a very common scenario.

Any pointers will be very helpful.

标签: c# com outlook
2条回答
神经病院院长
2楼-- · 2019-02-13 23:45

If you're using .NET's COM-interop features (you are) then you shouldn't need to worry about this.

COM tracks reference counts - and when the ref count reaches 0 COM objects get released automatically - and .NET takes care of working with the standard COM reference counting mechanism for you.

If you were P/Invoking into a C library things might be different - but you shouldn't have any worries in a standard scenario like yours.

查看更多
We Are One
3楼-- · 2019-02-13 23:45

Doing things like this:

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

will cause the references to not be disposed of even when you call ReleaseComObject because the reference to the child object hasn't been disposed of properly.

You should make the calls like this:

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

And you should dispose of each of these sub-objects, like session, in turn.

查看更多
登录 后发表回答