Как поток может уведомить объект, у которого нет дескриптора окна?

Я новичок в многопоточности, но не полный новичок. Мне нужно выполнить вызов веб-службы в рабочем потоке.

В основном потоке у меня есть форма (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;
6
задан Rob Kennedy 21 June 2011 в 14:16
поделиться

0 ответов

Другие вопросы по тегам:

Похожие вопросы: