I have in my one thread system that receives an html a TIdHttp and treats this html with IHTMLDocument2 as below:
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;
My problem is that this code is executed every 3 seconds, and every time this code executes, the memory consumption increases in 1.000k with this application will consume a lot of memory and slowing down over time until it locks, the two lines that make the memory increases are:
IDocTabela.Write(PSafeArray(System.TVarData(v).VArray));
and
ovTable := (IDocTabela.all.tags('TABLE') as IHTMLElementCollection).item(q, 0);
Note: I always destroy the IHTMLDocument2 component created with FreeAndNil() Any idea how to improve this code, so that this memory consumption stop occur?
Thanks!
You cannot do that. There is no
IHTMLDocument2
component. You are creating an instance of a COM object that implements theIHTMLDocument2
interface, and that interface is reference-counted. Its underlying implementation object is not based onTObject
(since it is not written in Delphi to begin with). An interface frees its underlying object automatically when its reference count falls to 0. Just let the variable go out of scope. If you must decrement the reference count manually, set the interface tonil
instead usingFreeAndNil()
:That being said, there is another way to load HTML into an
IHTMLDocument2
- query it for theIPersistStreamInit
interface and then call itsLoad()
method, which takes anIStream
as input. No need for putting the docuent into design mode, or processing window messages. You can get anIStream
for your HTML by putting your HTML into aTStringStream
orTMemoryStream
and then wrap it inside aTStreamAdapter
.