Освобождение Com-объекта

#c# #com #interop #release

#c# #com #взаимодействие #освобождение

Вопрос:

Какой более правильный способ повторно использовать com-объект, тип 1 или тип 2 или не имеет значения? (_document — это интерфейс)

     private IHTMLDocument2 _document;


    public HtmlDocument()
    {
        _document = new HTMLDocumentClass();
    }

    private void DisposeUnmanagedResources1()
    {
        if (_document != null)
        {
            Marshal.ReleaseComObject(_document);
            _document = null;
        }
    }

    private void DisposeUnmanagedResources2()
    {
        if (_document != null)
        {
            var doc = ((HTMLDocumentClass) _document);

            Marshal.ReleaseComObject(doc);
            doc = null;
            _document = null;
        }
    }
  

Комментарии:

1. DisposeUnmanagedResources1() кажется, этого было бы достаточно.

Ответ №1:

Правильнее всего ничего не делать — the .Net framework позаботится об уменьшении количества ссылок, когда объект больше не будет доступен.

На самом деле есть пара причин, по которым вам неследует ReleaseComObject вызывать ReleaseComObject — во-первых, потому что COM-объект на самом деле может быть управляемым COM-объектом, и в этом случае вызов _document завершится неудачей, и, во-вторых, потому что другие управляемые компоненты могут иметь ссылку на,, которую они все еще используют. (Вероятно, не в вашем примере, но вполне возможно в других случаях)

Смотрите эту статью в блоге для получения дополнительной информации.

Обновление: в ответе Брендана Макса есть пара интересных статей о том, почему вы можете захотеть явно вызывать ReleaseComObject в определенных ситуациях (обычно серверные приложения) для выпуска COM-объектов как можно скорее по соображениям производительности.

Ответ №2:

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

Внутренне Marshall.ReleaseComObject это просто приведет к уменьшению количества ссылок. Затем среда выполнения освободит собственный объект, если количество ссылок на него достигнет нуля, а оболочка будет уничтожена. Здесь, на управляемой стороне вещей, вы не имеете большого влияния.

Ответ №3:

Общий ответ здесь таков: ни то, ни другое. Среда CLR позаботится о выпуске COM-объектов за вас; вы должны использовать только Marshal.Освободите ComObject, если вам абсолютно необходимо взять на себя явный контроль над освобождением; например. для освобождения определенных объектов в определенном порядке. Как правило, это несколько сложные случаи. Самый обычный код должен просто позволить GC делать свое дело.

Также обратите внимание, что ReleaseComObject не сопоставляется напрямую с IUnknown::Release() — ознакомьтесь с этой статьей Криса Брумма на MSDN для получения более подробной информации о том, как это работает и когда ее использовать. Подробнее о типе случая, в котором вы хотели бы использовать ReleaseComObject, читайте в этой статье в блоге Visual Studio.