Remobjects_OpenXML & threaded TDaMemDataTable opening

Hi

Delphi 10.3.2/RoDA 10.0.0.1481

I have Remobjects_OpenXML defined for my client project which is working well and I do not use the uROComInit unit.

I’ve recently tried to convert opening some TDaMemDataTables in a thread using TTask.Run().

Sample code:

procedure TPatientData.OpenAsync;
begin
  TTask.Run(
    procedure
    begin
      tbl_Patients.Open;   // beforeOpen sets DynamicWhere clause
      tbl_SomeOtherTable.Open; 
      TThread.Synchronize(nil,
        procedure
        begin
          if assigned(AfterOpen) then
            AfterOpen(tbl_Patients); // will call back to the calling UI form
        end
      );
    end
  );
end;

The table(s) being opened are always on their own TDataModule which has it’s own Channel & Message components (as well as Bin2DataStreamer and RemoteDataAdapter).

In creating each datamodule instance I set the URL of the Channel and the ClientID of the Message from the main Channel and Message components on my ClientDataModule – so I think I’m right in saying this should make it safe to open the table(s) in a thread.

My problem is that I’ve noticed that I’m getting “CoIniitalize has not been called” errors when trying to open these tables in a thread, even though I have RemObjects_OpenXML defined.

I’ve temporarily solved the issue by wrapping the .open calls in CoInitialize/CoUninitialize calls but I’d like to be able to use these business data objects in non-Windows platforms.

How can I fix that so that I don’t need to use CoInitialize or winapi.activex ?

Thanks

Hi,

try to use workaround from this post:

it will call CoInitialize/CoUninitialize by demand on windows platforms only

1 Like

Hi,

Did that, and it’s still giving me “CoInitialise has not been called” errors.

I removed the “RemObjects_OpenXML” directive and re-built, and that made no difference - the error still occurs.

?

can you check in debugger what exactly code causes “CoInitialise has not been called” error, pls?

Hi,

It breaks on line 2724 of uROMSXML2_TLB :

class function CoDOMDocument60.Create: IXMLDOMDocument3;
begin
  Result := CreateComObject(CLASS_DOMDocument60) as IXMLDOMDocument3;
end;

Full call stack: https://imgur.com/a/gmTIL02

Thanks

Edit

If I carry on through the exceptions, I get to this one also:

Exception class EROException with message
‘Error creating MSXML Document classEOleSysError: CoInitialize has not been called, ClassID: {88D96A05-F192-11D4-A65F-0040963251E5}’.

you said that the same error was with RemObjects_OpenXML too.
what callstack if RemObjects_OpenXML is used?

Ok.

So now it’s working. I can’t make it fail again with RemObjects_OpenXML defined - which I swear it was initially.

I’ll keep testing and reply if I hit any more issues with this.

Thanks

this is as expected:
RemObjects_MSXML requires CoInitialize calls

Thanks again Evgeny :slight_smile:

Hi Evgeny,

If I don’t define RemObjects_OpenXML then should the I use the unit uROInitializedThread, or should I use uROComInit and call CoInitialize/CoUnInitialize in threads (i.e. TTask.Run()) ?

Thanks

Hi,

ROInitializedThread unit is a workaround when uROComInit cannot be used at all.
for example, std Open/SaveDialogs work incorrectly if uROComInit is used…

in other cases uROComInit should work correctly

I need std Open/Save dialogs to work correctly so I continue to use ROInitializeThread ?

Is there anything else I need to know - do I need to call CoInitialize etc in main thread?

if you are using ROInitializeThread solution, you shouldn’t call CoInitialize in main thread for correct working of RO SDK.

other code (non RO) may require additional calling of CoInitialize

Thanks for the clarification Evgeny.

Hi Evgeny,

I’m still hitting an issue with this. I have uROInitializedThread in the project source (second below FastMM4).

I am setting uROInitializedThread.ROInitializeThreads := TRUE as the first line of project source in the DPR.

I am using TTask.Run() to start a process that eventually opens a TDAMemDataTable on a datamodule - and this is still giving me “CoInitialize has not been called” errors when it tries to open the table.

Should I be getting this error or have I misunderstood?

The TDAMemDataTable is on a DataModule that may, or may not, be opened in a thread.

Thanks - I’m a little confused.

Stuart

Hi,

can you create a simple testcase that reproduces this behavior, pls?
you can drop it to support@ for keeping privacy

Hi Evgeny.

I’ll try and find time to do the sample.

Am I right in thinking what I described should work though?

Hi,

yes, it should work

Thanks - that’s helpful.

I’ll try and get a test case, but I have a huge backlog at the moment.

Thank you

you may use SOAPMessage, XMLDataStreamer, datXML field(s), DynamicWhere - all may have influence …