0

我在我的一个线程系统中接收一个 html 一个 TIdHttp 并使用 IHTMLDocument2 处理这个 html,如下所示:

 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 interface的 COM 对象的实例,并且该接口是引用计数的。它的底层实现对象不是基于的TObject(因为它一开始就不是用Delphi编写的)。当一个接口的引用计数降至 0 时,它会自动释放其底层对象。只要让变量超出范围即可。如果您必须手动减少引用计数,请将接口设置为nil使用FreeAndNil()

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

话虽如此,还有另一种将 HTML 加载到 an中的方法IHTMLDocument2- 查询它的IPersistStreamInit接口,然后调用它的Load()方法,该方法将 anIStream作为输入。无需将文档置于设计模式或处理窗口消息。您可以IStream通过将 HTML 放入TStringStreamorTMemoryStream然后将其包装在TStreamAdapter.

于 2015-06-24T22:45:52.240 回答