IXMLDocument in component accessed from different threads: where to call CoInitializeEx?

382 views Asked by At

I am writing a threadsafe component which logs xml string to a file. The component's public method will be called from many different (types of) threads. To simplify, in the example below the component only has to return an XML string from parameters.

My question is: can I avoid having to call CoInitializeEx in each thread? I want to keep the CoInitializeEx() and CoUnitialize and the IXMLDocument stuff inside the component so the callers don't need to worry about this. Is there a safe way for the threads to call that public function which would create a TXMLDocument on each call they make, even though the CoInitializeEx() would be called from the component (TMyLogger) which does not run in the calling thread? I'm not sure calling this function from multiple threads would corrupt the XMLDocument or not (since it's an interface).

Example to illustrate what I want to do:

TMyLogger = class(TComponent)
    public
        function logLineAsXml(const aLineName: String; const aAttribNames: Array of String; const aAttribValues: Array of String): String;
end;

function TMyLogger.logLineAsXml(const aLineName: String; const aAttribNames: Array of String; const aAttribValues: Array of String): String;
var
  doc: IXMLDocument;
  node: IXMLNode;
  I: LongInt;
begin
  doc := TXMLDocument.Create(Nil);
  try
    doc.XML.Clear;
    doc.Active := True;
    node := doc.AddChild(aLineName);
    for I := Low(aAttribNames) to High(aAttribNames) do begin
      node.Attributes[aAttribNames[I]] := aAttribValues[I];
    end;
    Result := node.XML;
  finally
    doc := nil;
  end;
end;

procedure TMyThread.Execute;
begin
    while not Terminated do begin
        DM.logger.logLineAsXml('log',['attrib1','[attrib2'],['x','y']); //must save line as  <log attrib1="x" attrib2="y"/>
    end;
end;
1

There are 1 answers

0
vincent On

Thanks for the hints everyone.

I made the thread the only instance that will access the TXMLDocument, the callers will add the data to the threads queue which will process it sequentially.