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;
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.