Освобождение объекта Com - PullRequest
1 голос
/ 27 апреля 2011

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

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

Ответы [ 3 ]

3 голосов
/ 27 апреля 2011

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

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

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

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

2 голосов
/ 27 апреля 2011

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

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

2 голосов
/ 27 апреля 2011

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

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

...