0

私は 1 つのスレッド システムで html を受け取り、TIdHttp を受け取り、この html を IHTMLDocument2 で次のように扱います。

 if IDocTabela = nil then
    IDocTabela := CreateComObject(Class_HTMLDOcument) as IHTMLDocument2
 else
    IDocTabela.clear;

 IDocTabela.designMode := 'on';
 if IENovo = False then
  while IDocTabela.readyState <> 'complete' do
     Application.ProcessMessages;

 v := VarArrayCreate([0, 0], VarVariant);
 v[0] := xHtml;
 IDocTabela.Write(PSafeArray(System.TVarData(v).VArray));
 IDocTabela.designMode := 'off';
 if IENovo = False then
  while IDocTabela.readyState <> 'complete' do
     Application.ProcessMessages;

 for q := 0 to (IDocTabela.all.tags('TABLE') as IHTMLElementCollection).Length -1 do
    begin
      ovTable := (IDocTabela.all.tags('TABLE') as IHTMLElementCollection).item(q, 0);

      for i := 0 to (ovTable.Rows.Length - 1) do
        begin
          for j := 0 to (ovTable.Rows.Item(i).Cells.Length - 1) do
            begin
              sTemp := TrimRight(TrimLeft(ovTable.Rows.Item(I).Cells.Item(J).InnerText));
              if (sTemp = 'Item') = true then
                 begin
                  bSai := True;
                  Break;
                 end;
            end;
            if bSai = True then
              Break;
        end;
      if bSai = True then
        Break;
    end;

私の問題は、このコードが 3 秒ごとに実行され、このコードが実行されるたびにメモリ消費量が 1.000k 増加することです。このアプリケーションは大量のメモリを消費し、ロックされるまで時間の経過とともに速度が低下します。メモリの増加は次のとおりです。

 IDocTabela.Write(PSafeArray(System.TVarData(v).VArray));

ovTable := (IDocTabela.all.tags('TABLE') as IHTMLElementCollection).item(q, 0);

注: 私は常に FreeAndNil() で作成された IHTMLDocument2 コンポーネントを破棄します。このコードを改善して、このメモリ消費が停止するようにする方法はありますか?

ありがとう!

4

1 に答える 1

4

私は常に FreeAndNil() で作成された IHTMLDocument2 コンポーネントを破棄します

それをしてはいけない。IHTMLDocument2 コンポーネントはありません。IHTMLDocument2 インターフェイスを実装する COM オブジェクトのインスタンスを作成していますが、そのインターフェイスは参照カウントされます。その基礎となる実装オブジェクトは基づいていませんTObject(そもそも Delphi で書かれていないため)。インターフェイスは、参照カウントが 0 になると、基になるオブジェクトを自動的に解放します。変数をスコープ外に出すだけです。参照カウントを手動でデクリメントする必要がある場合は、nil代わりに以下を使用してインターフェイスを に設定しFreeAndNil()ます。

IDocTabela := CreateComObject(Class_HTMLDOcument) as IHTMLDocument2
...
IDocTabela := nil;

そうは言っても、HTML を にロードする別の方法があります。インターフェイスをIHTMLDocument2クエリしてから、入力として を受け取るメソッドをIPersistStreamInit呼び出します。ドキュメントをデザイン モードにしたり、ウィンドウ メッセージを処理したりする必要はありません。HTML をまたはに入れ、 でラップすることにより、HTMLの を取得できます。Load()IStreamIStreamTStringStreamTMemoryStreamTStreamAdapter

于 2015-06-24T22:45:52.240 に答える