私はWebBrowserがテキストノードのようなものにアクセスできないので、WebBrowserコントロールでMSHTMLを使用しています。ここではいくつかの記事を見てきましたが、Web上では参照するすべてのCOMオブジェクトに対してReleaseComObject
と呼ぶ必要があります。だから、私はこれを行うと言う:すべてのMSHTMLオブジェクトでReleaseComObjectを必ず呼び出す必要はありますか?
var doc = myBrowser.Document.DomDocument as IHTMLDocument2;
私はdoc
を解放する必要がありますか?どのようにこのコードでbody
:
var body = (myBrowser.Document.DomDocument as IHTMLDocument2).body;
はすぐにそれらへの参照がなくなったとして、それらを解放するRCWによって包まれ、これらのオブジェクトではありませんか?もしそうでなければ、ガベージコレクタが起動するとすぐにそれらを解放するファイナライザ(Disposeを使用するのではなく)を使って、それぞれのラッパーを作成することをお勧めします(私は手動で心配する必要はありませんそれらを処分する)?
私のアプリケーションにはメモリリークがあり、これに関連していると思います。 ANTSメモリプロファイラによれば、第2世代のメモリを使用してオブジェクトのトップリストにあるMicrosoft.CSharp.RuntimeBinder.Semantics.LocalVariableSymbol
オブジェクトの束への参照を保持する関数(MSHTMLオブジェクトを使用する他の多くの機能)の1つは次のとおりです。
internal static string GetAttribute(this IHTMLDOMNode element, string name)
{
var attribute = element.IsHTMLElement() ? ((IHTMLElement)element).getAttribute(name) : null;
if (attribute != null) return attribute.ToString();
return "";
}
attribute
は単なる文字列なので、何が間違っているのかわかりません。ここで
ANTSプロファイラのインスタンスの保存グラフに示されている他の機能(私はFinalReleaseComObject
Sの束を追加しましたが、まだ示されている)である:私はReleaseComObject
を追加しましたが、機能はまだのようです
private void InjectFunction(IHTMLDocument2 document)
{
if (null == Document) throw new Exception("Cannot access current document's HTML or document is not an HTML.");
try
{
IHTMLDocument3 doc3 = document as IHTMLDocument3;
IHTMLElementCollection collection = doc3.getElementsByTagName("head");
IHTMLDOMNode head = collection.item(0);
IHTMLElement scriptElement = document.createElement("script");
IHTMLScriptElement script = (IHTMLScriptElement)scriptElement;
IHTMLDOMNode scriptNode = (IHTMLDOMNode)scriptElement;
script.text = CurrentFuncs;
head.AppendChild(scriptNode);
if (Document.InvokeScript(CurrentTestFuncName) == null) throw new Exception("Cannot inject Javascript code right now.");
Marshal.FinalReleaseComObject(scriptNode);
Marshal.FinalReleaseComObject(script);
Marshal.FinalReleaseComObject(scriptElement);
Marshal.FinalReleaseComObject(head);
Marshal.FinalReleaseComObject(collection);
//Marshal.FinalReleaseComObject(doc3);
}
catch (Exception ex)
{
throw ex;
}
}
何かへの参照を保持しています。ここに私の関数は、今どのように見えるかです:
private void InjectFunction(IHTMLDocument2 document)
{
if (null == Document) throw new Exception("Cannot access current document's HTML or document is not an HTML.");
try
{
IHTMLDocument3 doc3 = document as IHTMLDocument3;
IHTMLElementCollection collection = doc3.getElementsByTagName("head");
IHTMLDOMNode head = collection.item(0);
IHTMLElement scriptElement = document.createElement("script");
IHTMLScriptElement script = (IHTMLScriptElement)scriptElement;
IHTMLDOMNode scriptNode = (IHTMLDOMNode)scriptElement;
script.text = CurrentFuncs;
head.AppendChild(scriptNode);
if (Document.InvokeScript(CurrentTestFuncName) == null) throw new Exception("Cannot inject Javascript code right now.");
Marshal.FinalReleaseComObject(scriptNode);
Marshal.FinalReleaseComObject(script);
Marshal.FinalReleaseComObject(scriptElement);
Marshal.FinalReleaseComObject(head);
Marshal.FinalReleaseComObject(collection);
Marshal.ReleaseComObject(doc3);
}
catch (Exception ex)
{
MessageBox.Show("Couldn't release!");
throw ex;
}
}
MessageBox.Show("Couldn't release!");
ラインがヒットされることはありませんので、私はすべてが正常にリリースされていると仮定します。ここでANTSが示しものです:
私はそのサイトのコンテナの事が何であるか見当がつかない。
です例外がスローされた後にクリーンアップすることはできません... – prprcupofcoffee