我是多线程的新手,但不是一个完整的新手.我需要在工作线程中执行对Web服务的调用.
在主线程中,我有一个表单(TForm),它有一个私有数据成员(私有字符串),只有工作线程才能写入(我在它恢复之前将指针传递给线程).当工作线程完成其webservice调用并将结果响应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); finally CoUninitialize; end; end;
它工作得很好,但现在我想从数据模块(没有Handle)做同样的事情……所以我真的很感激一些有用的代码来补充我的工作模型.
编辑
我真正想要的是能够让我替换线路的代码(如果可能的话)
MyWorkerThread.SenderHandle := self.Handle;
同
MyWorkerThread.SenderHandle := GetHandleForThisSOAPDataModule;
解决方法
我之前使用过这种技术取得了一些成功:
Sending messages to non-windowed applications
基本上,在通过AllocateHWND获得的句柄上使用第二个线程作为消息泵.这无疑是令人恼火的,你最好使用库来处理所有细节.我更喜欢OmniThreadLibrary,但还有其他 – 见How Do I Choose Between the Various Ways to do Threading in Delphi?和Delphi – Threading frameworks.