MEGA Search
20.3 Million


Sign Up
From: David Markie  
Subject: Using TXMLDocument in a Thread
NewsGroup: borland.public.delphi.vcl.components.using.win32
Date Posted: 4-Aug-2005 at 8:40:2 PST
I have a D7 app that uses a TXMLDoucument successfully in the main thread, I
want to move some XML code into a TThread, passing the existing XMLDocument
into the thread fails when I call:-

XMLDocument1.XML.Clear;
XMLDocument1.LoadFromFile(XMLFilename);  // fails here - filename is valid
XMLDocument1.Active:=true;

The error message is >>...raised exception class EOleSysError with message
'CoInitialise has not been called'<<

Creating a new TXMLDocument within the thread also fails at the same point.

Is there an inherent problem in using TXMLDocument inside a Thread


Thanks


David



From: Remy Lebeau \(TeamB\)  
Subject: Re: Using TXMLDocument in a Thread
NewsGroup: borland.public.delphi.vcl.components.using.win32
Date Posted: 4-Aug-2005 at 18:20:5 PST
"David Markie"  wrote in message
news:42f2ae37@newsgroups.borland.com...

> is this the correct use of CoInitialize and CoUnInitialize

Yes, but that is not what is wrong with your code.

> as the XML code still fails but this time with an AV

You are not using TXMLDocument properly.  When instantiated dynamically,
TXMLDocument acts as an interface, not a component.  As such, you need to
treat it as an interface.  In which case, you may as well use real
interfaces instead, via the NewXMLDocument() and related functions, ie:

    procedure TXMLFileThread.Execute;
    var
        XMLDoc: IXMLDocument;
    begin
        CoInitialize(nil);
        try
            XMLDoc := NewXMLDocument;
            // perform XML Stuff...
        except
            // ReportErrors;
        end;
        CoUnInitialize();
    end;


Gambit



From: David Markie  
Subject: Re: Using TXMLDocument in a Thread
NewsGroup: borland.public.delphi.vcl.components.using.win32
Date Posted: 5-Aug-2005 at 1:9:56 PST
My thread execute method is shown below, is this the correct use of
CoInitialize and CoUnInitialize, as the XML code still fails but this time
with an AV

procedure TXMLFileThread.Execute;
begin
  CoInitialize(nil);
  try
    FXMLDocument:=TXMLDocument.create(nil);
    try
      perform XML Stuff... // still fails here but this time with an AV
    finally
      FreeAndNil(FXMLDocument);
    end;
  except
    // ReportErrors;
  end;
  CoUnInitialize();
end;

The code that works is contained in a unit with the TXMLDocument declared
as:-

unit XML_Unit;
interface
uses
  classes,sysutils,forms,XMLIntf,XMLDoc;

implementation
var
  XMLDocument1: TXMLDocument;

XML methods....

initialization
  XMLDocument1:=TXMLDocument.create(application);
finalization

end.

The code in the unit failed when XMLDocument1:=TXMLDocument.create(nil); was
used so I had to find a willing owner hence 'uses forms' and
'create(application)'

It did feel like a fudge when I wrote it but could not see a clear solution


David



From: Ronaldo Souza  
Subject: Re: Using TXMLDocument in a Thread
NewsGroup: borland.public.delphi.vcl.components.using.win32
Date Posted: 4-Aug-2005 at 13:30:34 PST
> 
> If an exception occurs, CoUnitialize() is being bypassed.  You should be
> placing the CoInitialize/CoUninitialize() outside the try..except block:
> 
Good catch Gambit! Thanks.


From: Remy Lebeau \(TeamB\)  
Subject: Re: Using TXMLDocument in a Thread
NewsGroup: borland.public.delphi.vcl.components.using.win32
Date Posted: 4-Aug-2005 at 1:26:26 PST
"Ronaldo Souza"  wrote in message
news:42F1CC36.3010202@nospam.org...

> Should look something like this:

If an exception occurs, CoUnitialize() is being bypassed.  You should be
placing the CoInitialize/CoUninitialize() outside the try..except block:

    procedure TMyXMLThread.Execute
    begin
        CoInirialize(nil);
        try
            // ...
        except
            //No exceptions should escape...
        end;
        CoUninitialize;
    end;

Alternatively, override the thread's DoTerminate() method as well.  Then you
don't need the try..except at all, as it won't matter anymore if an
exception is thrown:

    procedure TMyXMLThread.Execute
    begin
        CoInirialize(nil);
        // ...
    end;

    procedure TMyXMLThread.DoTerminate;
    begin
        CoUninitialize;
    end;


Gambit



From: Remy Lebeau \(TeamB\)  
Subject: Re: Using TXMLDocument in a Thread
NewsGroup: borland.public.delphi.vcl.components.using.win32
Date Posted: 4-Aug-2005 at 1:23:47 PST
"David Markie"  wrote in message
news:42f1c642$1@newsgroups.borland.com...

> I want to move some XML code into a TThread, passing the
> existing XMLDocument into the thread

You should not do that.  TXMLDocument is tied to the thread that creates it.
This is especially important if you use MSXML as the core engine, as MSXML
is a COM object and thus cannot be passed around between multiple threads.
You are best off simply creating a new TXMLDocument instance in the thread's
Execute() method to ensure proper usage for that thread.

> The error message is >>...raised exception class EOleSysError
> with message 'CoInitialise has not been called'<<
>
> Creating a new TXMLDocument within the thread also fails
> at the same point.

The error is self-explanatory.  Your thread did not call the CoInitialize()
function before accessing the TXMLDocument.  Which likely meansthat you are
indeed using the MSXML engine.  All threads much call either CoInitialize()
or CoInitializeEx() before accessing any COM objects and/or functions.


Gambit



From: Ronaldo Souza  
Subject: Re: Using TXMLDocument in a Thread
NewsGroup: borland.public.delphi.vcl.components.using.win32
Date Posted: 4-Aug-2005 at 5:5:10 PST
David,

Add a call to CoInitialise and  CoUnitiliase in the Execute procedure of 
your thread. Should look something like this:

uses
   ActiveX;

procedure TMyXMLThread.Execute
begin
   try
     CoInirialize(nil);
     . . .
     while not terminated do
     begin
       . . .
       //Do XML stuff here
       . . .
     end;
     . . .
     CoUninitialize;
   except
     //No exceptions should escape...
   end;
end;


Good luck,
Ronaldo



From: David Markie  
Subject: Re: Using TXMLDocument in a Thread
NewsGroup: borland.public.delphi.vcl.components.using.win32
Date Posted: 7-Aug-2005 at 16:22:34 PST
All working now - thanks for the assistance

David