Использование Microsoft.MSHTML в цикле, утечка памяти
-
19-09-2019 - |
Вопрос
Привет, я пытаюсь использовать библиотеку Microsoft.MSHTML (версия 7.0.3300.0) для извлечения основного текста из строки HTML.Я объединил эту функциональность в один вспомогательный метод GetBody(string).
При вызове в бесконечном цикле процессу в конечном итоге не хватает памяти (что подтверждается наблюдением за использованием памяти в диспетчере задач).Я подозреваю, что проблема связана с неправильной очисткой объектов MSHTML.Что я делаю не так?
Мое текущее определение GetBody(строка):
public static string GetBody(string html)
{
mshtml.IHTMLDocument2 htmlDoc = null;
mshtml.IHTMLElement bodyElement = null;
string body;
try
{
htmlDoc = new mshtml.HTMLDocumentClass();
htmlDoc.write(html);
bodyElement = htmlDoc.body;
body = bodyElement.innerText;
}
catch (Exception ex)
{
Trace.TraceError("Failed to use MSHTML to parse HTML body: " + ex.Message);
body = email.Body;
}
finally
{
if (bodyElement != null)
Marshal.ReleaseComObject(bodyElement);
if (htmlDoc != null)
Marshal.ReleaseComObject(htmlDoc);
}
return body;
}
Редактировать:утечка памяти была связана с кодом, используемым при заполнении значения для html.В данном случае это было Outlook Redemption.
Решение
Я давно не использовал mshtml, но разве у интерфейса IHTMLElement2 нет метода закрытия?Вы пробовали туда позвонить?
Как долго работал контур, прежде чем утечка стала очевидной?
Я посмотрю, смогу ли я покопаться в имеющемся здесь устаревшем коде, использующем mshtml, и посмотреть, как разработчики выпустили объекты.
РЕДАКТИРОВАТЬ:
Старый код, который мы здесь имеем, вызывает закрытие HTMLDocument2, а затем освобождение com-объекта в том виде, в каком он у вас есть.
Однако следует отметить одну вещь: метод ReleaseComObject вызывается в цикле до тех пор, пока не вернет ноль.Это обеспечит освобождение всех оберток com и исходного объекта, об этом есть примечание. здесь.