Выпуск COM-объекта в C # - PullRequest
       13

Выпуск COM-объекта в C #

5 голосов
/ 13 февраля 2012

Я знаю, что это обсуждалось ранее, но я не мог найти удовлетворительный ответ.

У меня есть файл электронной почты (.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, он не был выпущен должным образом.

Что я могу сделать, чтобы убедиться, что он выпущен правильно. закрытие и повторное открытие файла - очень распространенный сценарий.

Любые указатели будут очень полезны.

Ответы [ 2 ]

6 голосов
/ 13 февраля 2012

Если вы используете (.) Функции COM-взаимодействия .NET, вам не нужно беспокоиться об этом.

COM отслеживает количество ссылок - и когда количество ссылок достигает 0, COM-объекты автоматически освобождаются - и .NET позаботится о работе со стандартным механизмом подсчета ссылок COM для вас.

Если бы вы были P / Invoking в библиотеке C, все могло бы быть по-другому - но вам не следует беспокоиться о стандартном сценарии, подобном вашему.

3 голосов
/ 13 февраля 2012

Делать такие вещи:

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

приведет к тому, что ссылки не будут удалены даже при вызове ReleaseComObject, поскольку ссылка на дочерний объект не была удалена должным образом.

Вы должны делать звонки так:

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

И вы должны по очереди распоряжаться каждым из этих подобъектов, например сеансом.

...