I'm having a hard time wrapping my head around using Synchronize from a TWebActionItem
.
My webservice is a visual program with form TFormWebServices
var FormWebServices: TFormWebServices;
This has a property FWebBrokerBridge: TIdHTTPWebBrokerBridge
The FWebBrokerBridge
registers TWebModuleWebServices
as the classes to use for each incoming call:
FWebBrokerBridge.RegisterWebModuleClass(TWebModuleWebServices);
The TWebActionItem
items in this class do the work reading a TWebRequest
and writing a TWebResponse
.
There is one handler that needs to use some VCL visual rendering (shared code with another app) and I want to Synchronize this with the main thread (FormWebServices
).
Stub:
TWebModuleWebServices = class(TWebModule)
procedure WebModuleWebServicesTTGetDynReportAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
procedure WebModuleAfterDispatch(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
private
FResponse: TResBase; // JSON response object
end;
procedure TWebModuleWebServices.WebModuleWebServicesTTGetDynReportAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
lFrmDynRapport : TFormDynRapport; // A form containing the common code, has VCL components
begin
lResponse := (FResponse as TResGetDynReport); // TResGetDynReport = class(TResBase)
// ...
lFrmDynRapport := TFormDynRapport.Create(Self);
try
with lFrmDynRapport do
begin
// Do visual stuff with grids, read grid settings, fill lResponse with info specific for this webaction
end
finally
end
// ...
end;
procedure TWebModuleWebServices.WebModuleAfterDispatch(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var lJSO: ISuperObject; // SuperObject library
begin
lJSO := FResponse.ToJson;
// ...
Response.Content := lJSO.AsString;
Handled := true;
end;
Now how can I properly Synchronize the try/finally block? I can get at the current thread and do something simple like:
lThread := TThread.CurrentThread;
TThread.Synchronize(lThread,procedure
begin
FormWebServices.MmoLog.Lines.Add('Synchronize test');
end);
but for anything more complex I'm stuck.
Defining local procedures and feeding these into Synchronize does not work (E2555 cannot capture symbol).
How can I extract the try/finally block so that I can properly execute it in the context of FormWebServices?
The trick is to put the entire block in an anonymous method (thanks for the tip, David):
if lFlexRapDM.DesignerCustomOpenDoc(lFlexRapDM.TimeTellReport) then
begin
.....
lThread := TThread.CurrentThread;
TThread.Synchronize(lThread,procedure
var l,lIndex : integer;
...
begin
lFrmDynRapport := TFormDynRapport.Create(Self);
try
with lFrmDynRapport do
begin
...
end; // with FrmDynReport
finally
lFrmDynRapport.Free;
end;
end);
...
end // if lFlexRapDM.DesignerCustomOpenDoc