Exclude a remote SOAP call from a stream

This is the extension / next step of this question that I asked a few minutes ago.

I have a Delphi application with the main form and stream. Every X seconds, the thread makes a web service request for the remote object. Then it returns to the main form, which processes the user interface with new information.

I previously used the TTimer object in my thread, and when the TTimer callback function was run, it was executed in the context of the main thread (but the request for remote web services did work). This pretty distorted the purpose of the individual thread, and so now I have a simple loop and sleep procedure in my Execute thread function. The problem is that an exception is thrown when returning from GetIMySOAPService ().

procedure TPollingThread.Execute; var SystemStatus : TCWRSystemStatus; begin while not Terminated do begin sleep(5000); try SystemStatus := GetIMySOAPService().GetSystemStatus; PostMessage( ParentHandle, Integer(apiSystemStatus), Integer(SystemStatus), 0 ); SystemStatus.DataContext := nil; LParam(SystemStatus) := 0; except end; end; end; 

Can someone tell me why this exception is thrown when this function is called from a thread? I am sure that I am losing sight of something fundamental and simple.

Thanks Duncan

+4
source share
2 answers

In your Execute() method, you must call CoInitialize and CoUnitialize to install and tear down the COM library.

Your main thread automatically does this in the Application.Initialize() procedure, however other calls require a CoInitialize call before calling the COM functions.

Make sure you call CoInitialize in the Execute() method, and not in the constructor, because the constructor is executed in the parent thread (usually in the main thread). This is not where you need it. It must be called from the thread you plan to call COM calls.

I recommend using this format:

 try // OleCheck will raise an error if the call fails OleCheck(CoInitializeEx(NIL, COINIT_MULTITHREADED or COINIT_SPEED_OVER_MEMORY)); try // Do work here finally CoUninitialize; end; except // We failed, do something end; 

This allows you to catch an error if it is not initialized and ensures that you call CoUninitialize .

+5
source

For my future ... I needed to Socialize and Merge into my Execute method:

 procedure TPollingThread.Execute; begin CoInitialize(nil); while not Terminated do begin // ... end; CoUnInitialize; end; 
+2
source

Source: https://habr.com/ru/post/1305473/


All Articles