Jump to content

PatV

Members
  • Content Count

    39
  • Joined

  • Last visited

Posts posted by PatV


  1. Hi,

     

    could someone tell me what's wrong here, I'm returning an IInterface  as needed so ... 

     

    [dcc32 Error] clsInit.pas(313): E2250 There is no overloaded version of 'SetThreadDataFactory' that can be called with these arguments

     

    ( in OtlThreadPool  ; TOTPThreadDataFactoryFunction = function: IInterface; )


    function TFConfig.CreateThreadPool(aHandle : THandle ; aConfig : rConnectionConfig ;  aValue: string) : iOmniThreadPool;
    begin
      result  := otlThreadPool.CreateThreadPool(aValue);
      result.MaxExecuting := result.NumCores;
      result.SetThreadDataFactory

      (
         function  : IInterface
         begin
           result:=CreateConnectionPoolData(aHandle,aConfig);
         end
      );

    end;

     

    I have defined  CreateConnectionPoolData as follow

     

    function CreateConnectionPoolData(const aHandle : THandle ; const aConfig : rConnectionConfig) : IInterface;
    var
      aPool : IConnectionPoolData;
    begin
      aPool := TConnectionPoolData.Create;
      aPool.WithHandle(aHandle).WithConnectionConfig(aConfig);
      result:=aPool;
    end;

     

      IConnectionPoolData = interface
        function WithHandle(const aValue : HWND) : IConnectionPoolData ;
        function WithConnectionConfig(aValue : rConnectionConfig) : IConnectionPoolData ;
      end;

     

    Thanks

     

    Patrick

     

     

     

     

     

     

     

     


  2. Delphi 10.3

    Omnithead 3.07.5

     

    Hi All,

     

    I'm just a little lost, I would like to pass parameters to the data factory, I know I can pass function like this

     

    TOTPThreadDataFactoryFunction = function: IInterface;
    TOTPThreadDataFactoryMethod = function: IInterface of object;

     

    and my function is like 

     

    {-------------------------------------------------------------------------------------------------}

     

    function TFConfig.CreateThreadPool(aHandle : THandle ; aConfig : rConnectionConfig ;  aValue: string) : iOmniThreadPool;
    var
     iOmniValue : TOmniValue;
    begin
      iOmniValue := TOmniValue.FromRecord<rConnectionConfig>(aconfig);

      result  := otlThreadPool.CreateThreadPool(aValue);
      result.MaxExecuting := result.NumCores;

     

      result.SetThreadDataFactory
      (
        (function (aHandle : THandle ; aConfig : TOmniValue) : IInterface
         begin
           result:=Function : IInterface
                   begin
                      result:=  ??
                   end;
         end
        )(aHandle,iOmniValue
    )
      );

    end;

     

    {-------------------------------------------------------------------------------------------------}

     

    rConnectionConfig is a record containing info on to be able to connect to the datamodule

     

      RConnectionConfig = record
        User            : string;
        Password        : string;
        Database        : string;
        Protocol        : string;
        Port            : integer;
        HostName        : string;
        LibraryLocation : string;
        ModuleName      : string;
      end;

     

    Could someone help me with this

     

    Thanks

     

    Patrick

     

     

     

     

     

     

     

     

     


  3. Delphi 10.3

    Omnithead 3.07.5

     

    Hi all,

     

    I'm testing and playing with the sample 24_ConnectionPool, so in the main form I've added

     

    procedure TfrmConnectionPoolDemo.btnScheduleClick(Sender: TObject);

    var
      i : integer;
      Params  : TParameters;

    begin

     WithParamsReset(Params);
     WithParam(Params,cDteFrom,'2019/01/01',dtString);

     WithParam(Params,cDteTo  ,'2019/09/01',dtString);
     

     for i:=0 to 99 do    // for testing purpose launch 100 task

     begin
        Log(Format('Creating task %d',));
        CreateTask(Worker,format('%0.2d',))
          .MonitorWith(OTLMonitor)
          .SetParameter('Params',TOmniValue.FromArray<rParameter>(Params))
          .SetParameter('ProcName','prc_ProcedureToCall')
          .Schedule(FConnectionPool); 

     end;
    end;

     

    now my question is ;

     

    how can I retreive the result of the data connection in an object and send it from task Worker to the main thread ?

     

    I was thinking about msg.msgData  from IOmniMessage  and retreive it through OTLMonitor  or insert a TOmniTaskInvokeFunction  into my Worker task

     

    What is the best way ?

     

    Thanks 

     

    Patrick

     

     

     

     

     

     

     

     


  4. Delphi 10.3

    Omnithead 3.07.5

     

    Hi All

     

    here is a definition of an array of ..

     

      TpDataType  = (dtNone, dtInteger, dtDateTime, dtString, dtBlob);

     

      rParameter = record
        Field   : string;
        Value   : Variant;
        AsValue : TpDataType;
      end;

     

      TParameters = array of rParameter;

     

    I would like to pass it to a worker as parameter, so 

     

        CreateTask(Worker)
          .MonitorWith(OTLMonitor)
          .SetParameter('Params',TOmniValue.Create([Params]);   

     

    I've tried also

          .SetParameter('Params',TOmniValue.FromArray<TParameters>(Params))

     

    and convert it again like 

     

    function TConnectionPoolData.WithParameters(const aValue : TOmniValue)  : IConnectionPoolData;

    begin
      FParams :=  aValue.CastTo<TParameters>;

      Result:=Self;

    end;
     

    But it's not working as expected, as I'm getting bunch of data   

     

    Do I need to use a class instead ?

     

    Thanks 

     

    Patrick

     


     

     

     

     


  5. Found the prob.... it's too quick, I need to introduce a delay in my loop and everything is working

     

    now if you have any suggestions, you're welcome

     

     

     

    Hi All,

     

    I'm using Delphi 10.3

     

    As testing, I've a main form 

    image.png.765dd1719b35e9a54d022be0cbf79fa1.png

     

    when I click on MyForm Create Thread  Button, I launch the code bellow ;

     

    image.png.6171e0fbd76b8e457e00b93e3779c5fd.png

     

    I create a form TForm.Create(Self)  and I include a frame in it TFrm.Create(Self)

    GetTGUIDString simply convert number from TGIUID.NewGuid.ToString to letter, and remove special char to get a random name.

     

    In My  Frame, 

     

    I have defined a Thread ;

     

      TThDb = class(TThread)
      private
        FOwner    : TComponent;
        FDM       : TFDb;      //
     is a datamodule who will be created within the tread
        FEvent    : TEvent;
        FError    : TFError;
        FRet      : TFRet;
        FAgs      : string;
        FWhenDone : PrcDone;
        procedure InitializeDatabase;
        procedure ConnectToDatabase;
        Procedure WorkOnData;
        function  LoadData : TThDb;
        procedure Execute; override;
      public
        constructor Create(bSuspended : boolean);
        destructor  Destroy; override;
        property Event : TEvent read FEvent write FEvent;
        function WhenDone(aValue : PrcDone) : TThDb;
        function WithAgencies(aValue : string) : TThDb;
        function WithOwner(aValue : TComponent) : TThDb;
        procedure Start;     //
     initialise the connection to the database the first time
        procedure ReStart; // update the variable in the query/procedure
      end;

    {------------------------------------------------------------------------------}

    procedure TTHDB.InitializeDatabase;
    begin
     
    CoInitialize(Nil);
      FDM := TFDb.Create(nil);
      FDM.Connection.ReadOnly:=True;
      CoUninitialize;
    end;

     

    {------------------------------------------------------------------------------}

    procedure TTHDB.ConnectToDatabase;
    var
      rParam    : rConnectionConfig;
    begin
       rParam := GetConnectionConfig;
       rParam.ModuleName := GetTGUIDString;
       FDM.InitConnection(rParam);
       FDM.Connect;
    end;

     

    {------------------------------------------------------------------------------}

    procedure TThDb.ReStart;
    begin
      synchronize(
      procedure()
      begin
        LoadData.WorkOnData;
      end);
    end;

    {------------------------------------------------------------------------------}

     

    Procedure TTHDB.WorkOnData;
    begin
       if Assigned(FWhenDone) then FWhenDone(FRet);
       Application.ProcessMessages;
    end;

    {------------------------------------------------------------------------------}


    function TThDb.LoadData : TThDb;
    var
      aFiles : TFFilesStatus;
    begin
      ... some work ...
       FRet.FValue:=TValue.From<TFFilesStatus>(aFiles);
       FRet.FId  := FAgs;
       result:=Self;
    end;

    {------------------------------------------------------------------------------}

     

    procedure TThDb.Start;
    begin
      Resume;
    end;

     

    {------------------------------------------------------------------------------}

     

    procedure TThDb.Execute;
    begin
       InitializeDatabase; 

      ConnectToDatabase;

      restart;
    end;


    {------------------------------------------------------------------------------}

    {------------------------------------------------------------------------------}

    {------------------------------------------------------------------------------}

     

    and in the frame constructor I have 

     

    constructor TFrm.Create(aOwner: TComponent);
    begin
      inherited Create(aOwner);
      FError := TFError.Create;
      FTh:=TThDb.Create(True);
      FTh.WithOwner(Self).WhenDone(UpdateGrid);
    end;

     

    and launch the following code ;

     

    var
     i : integer;
    begin
     FTh.Start;
     i:=1;
     while True do
       with FTh do
        if Event.waitfor(0)=wrSignaled then
        begin
           Event.ResetEvent;
           WithAgencies(Format('%0.2d',)).ReStart;
           inc(i);
           if i>99 then i:=1;
           if Terminated then Break;
        end else Application.ProcessMessages;
     FTh.Free;

     

    As you see I've a loop ( it's nomal in my test), now If I click again on MyForm Create Thread  Button from the main form, I create another TForm with a TFrrame in, and the thread connected to the database from the previous form/frame  stop working.

     

    Is it a normal behaviour or am I missing something ? What I would like of course is that both form with thread in  are still running.

     

    Thanks for your help

     

    Patrick

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     


  6. Hi All

     

    Delphi 10.3  / OmniThread 3.07.7

     

    I'm playing with forms and threads and I'm a little lost...

     

    From a main form  (FormMaster) , I have a button, when I click on it , it create another form (FormGrid)

     

    in FormGrid (1), I create a class (TFOmniDb) and create everything within the Thread (as the two fish sample)  and update a grid on (1).

     

    now, If I create another FormGrid (2),  and launch  also the thread, then eveything on (1) stop instead of running in background)

     

    Could yoy help me to find the way of doing it ?

     

    Regards

     

    Patrick

     

    TFOmniDb = class
      private
        FId         : string;
        FDo         : TpDo;
        FDm         : TDM;
        FWorker     : IOmniBackgroundWorker;
        FRConfig    : RConnectionConfig;
        FPrcDone    : TOmniWorkItemDoneDelegate;
        FPrcToDo    : TPrcLoadData;

        FOnConnectionOpen : TNotify;

        procedure InitializeDatabase(var taskState: TOmniValue);
        procedure FinalizeDatabase(const taskState: TOmniValue);
        procedure ConnectToDatabase(const workItem: IOmniWorkItem);

        procedure FirstStage(dataModule : TDM);

        procedure LoadData(const workItem : IOmniworkItem);
        Procedure WorkOnData(const Sender: IOmniBackgroundWorker; const workItem: IOmniWorkItem);
      public

      ...
      end;

     

    {------------------------------------------------------------------------------}

    procedure TFOmniDb.AfterConstruction;
    begin
      inherited;
      then  FWorker := Parallel.BackgroundWorker
                  .Initialize(InitializeDatabase)
                  .Finalize(FinalizeDatabase)
                  .Execute:
     

     

×