2016-12-27 2 views
0

J'ai du mal à faire le tour en utilisant Synchroniser depuis un TWebActionItem.Extraction du code de TWebAction pour Synchronize() ing dans le thread principal?

Mon webservice est un programme visuel avec la forme TFormWebServices

var FormWebServices: TFormWebServices; 

Cela a une propriété FWebBrokerBridge: TIdHTTPWebBrokerBridge
Les FWebBrokerBridge registres TWebModuleWebServices que les classes à utiliser pour chaque appel entrant:

FWebBrokerBridge.RegisterWebModuleClass(TWebModuleWebServices); 

Le TWebActionItem articles dans cette classe font le travail en lisant un TWebRequest et en écrivant un TWebResponse.

Il existe un gestionnaire qui doit utiliser un rendu visuel VCL (code partagé avec une autre application) et je souhaite synchroniser cela avec le thread principal (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; 

Maintenant, comment puis-je bien synchroniser le bloc try/finally? je peux obtenir au thread courant et faire quelque chose de simple comme:

lThread := TThread.CurrentThread; 
TThread.Synchronize(lThread,procedure 
    begin 
    FormWebServices.MmoLog.Lines.Add('Synchronize test'); 
    end); 

mais pour quelque chose de plus complexe, je suis coincé.
La définition des procédures locales et leur chargement dans Synchronize ne fonctionne pas (E2555 ne peut pas capturer le symbole).
Comment puis-je extraire le bloc try/finally afin de pouvoir l'exécuter correctement dans le contexte de FormWebServices?

Répondre

0

L'astuce est de mettre le bloc entier dans une méthode anonyme (merci pour la pointe, 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