Я новичок в многопоточности, но не полный новичок. Мне нужно выполнить вызов веб-службы в рабочем потоке.
В основном потоке у меня есть форма (TForm) с частным элементом данных (закрытая строка), в которую будет записывать только рабочий поток (я передаю a указатель на него в поток перед его возобновлением). Когда рабочий поток завершил вызов веб-службы и записал результирующий XML-ответ в закрытый член формы, рабочий поток использует PostMessage для отправки сообщения дескриптору формы (которое я также передал в поток перед его возобновлением).
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;
Он отлично работает, но теперь я хочу сделать то же самое из модуля данных (у которого нет дескриптора) ...так что я был бы очень признателен за некоторый полезный код в дополнение к имеющейся у меня рабочей модели.
EDIT
Что мне действительно нужно, так это код (если возможно), который позволил бы мне заменить строку
MyWorkerThread.SenderHandle := self.Handle;
на
MyWorkerThread.SenderHandle := GetHandleForThisSOAPDataModule;