I'm new to multithreading, but not a complete novice. I need to perform a call to a webservice in a worker thread.
In the main thread I have a form (TForm) with a private data member (private string) that only the worker thread will write to (I pass the a pointer to it into the thread before it resumes). When the worker thread has finished its webservice call and written the resultant response xml to the private member on the form, the worker thread uses PostMessage to send a message to the form's handle (which I also passed into the thread before it resumed).
interface
const WM_WEBSERVCALL_COMPLETE = WM_USER + 1;
type
TWebServiceResponseXML = string;
PWebServiceResponseXML = ^TWebServiceResponseXML;
TMyForm = class(TForm)
...
private
...
fWorkerThreadID: Cardinal;
fWebServiceResponseXML: TWebServiceResponseXML;
public
...
procedure StartWorkerThread;
procedure OnWebServiceCallComplete(var Message: TMessage); Message WM_WEBSERVCALL_COMPLETE;
end;
TMyThread = class(TThread)
private
protected
procedure Execute; override;
public
SenderHandle: HWnd;
RequestXML: string;
ResponseXML: string;
IMyService: IService;
PResponseXML: PWebServiceResponseXML;
end;
implementation
procedure TMyForm.StartWorkerThread;
var
MyWorkerThread: TMyThread;
begin
MyWorkerThread := TMyThread.Create(True);
MyWorkerThread.FreeOnTerminate := True;
MyWorkerThread.SenderHandle := self.Handle;
MyWorkerThread.RequestXML := ComposeRequestXML;
MyWorkerThread.PResponseXML := ^fWebServiceResponseXML;
MyWorkerThread.Resume;
end;
procedure TMyForm.OnWebServiceCallComplete(var Message: TMessage);
begin
// Do what you want with the response xml string in fWebServiceResponseXML
end;
procedure TMyThread.Execute;
begin
inherited;
CoInitialize(nil);
try
IMyService := IService.GetMyService(URI);
ResponseXML := IMyService.Search(RequestXML);
PResponseXML := ResponseXML;
PostMessage(SenderHandle, WM_WEBSERVCALL_COMPLETE, 0, 0);
finally
CoUninitialize;
end;
end;
It works great, but now I want to do the same thing from a datamodule (which doesn't have a Handle)... so I would really appreciate some useful code to supplement the working model I have.
EDIT
What I really want is the code (if possible) that would allow me to replace the line
MyWorkerThread.SenderHandle := self.Handle;
with
MyWorkerThread.SenderHandle := GetHandleForThisSOAPDataModule;