#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.