私はマルチスレッドは初めてですが、完全な初心者ではありません。ワーカー スレッドで Web サービスの呼び出しを実行する必要があります。
メイン スレッドには、ワーカー スレッドのみが書き込むプライベート データ メンバ (プライベート文字列) を持つフォーム (TForm) があります (スレッドが再開する前に、そのポインタをスレッドに渡します)。ワーカー スレッドが Web サービス呼び出しを終了し、結果の応答 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;
それはうまく機能しますが、今はデータモジュール(ハンドルを持たない)から同じことをしたいので、私が持っている作業モデルを補足する便利なコードを本当に感謝しています。
編集
私が本当に欲しいのは、(可能であれば)行を置き換えることができるコードです
MyWorkerThread.SenderHandle := self.Handle;
と
MyWorkerThread.SenderHandle := GetHandleForThisSOAPDataModule;