Jump to content

gorepj

Members
  • Content Count

    10
  • Joined

  • Last visited

Posts posted by gorepj


  1. Agreed David.  I cannot get this to work using Console.  I do not get any values outputted at all.

     

    program OTLInvoke;

    {$APPTYPE CONSOLE}

    {$R *.res}

    uses
      System.SysUtils, otltask, OtlTaskControl;

    procedure TestTask(const Task: IOmniTask);
      function CaptureValue(Value: Integer): TOmniTaskInvokeFunction;
      begin
        Result := procedure begin Writeln(Value.ToString); end;
      end;

      var
      i: Integer;
      begin
        Writeln('Test Using Invoke');
        for I := 0 to 9 do
          begin
            Task.Invoke(CaptureValue(i));
          end;
        WriteLn('');

        WriteLn('Press any key');
      end;

    begin
      try
        { TODO -oUser -cConsole Main : Insert code here }
        createTask(TestTask).
        Run;
        Readln;

      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    end.


  2. Thank you for your answers again.  The scenario doesn't lend itself to a Consol app.  So here is a test case using a form with a button and a memo.

    I tried also using the array of TMyProc and that also did not work.  I kept getting access violations.

     

    My goal actually is to learn the best practice simple approach in updating the GUI from within a running IOmniTask thats all. Just like Synchronize from a TThread but the Omnithread way.

    I thought it may be using invoke but maybe its perhaps using Comm.Send to an omnithreadMonitor.

     

    unit OTLInvokeMain;

    interface

    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, OtlTask, OtlTaskControl, Vcl.StdCtrls;

    type
      TMyForm = class(TForm)
        Memo: TMemo;
        Button: TButton;
        procedure ButtonClick(Sender: TObject);
      private
        { Private declarations }
      procedure TestTask(const Task: IOmniTask);
      public
        { Public declarations }
      end;

    var
      MyForm: TMyForm;

    implementation

    {$R *.dfm}

    procedure TMyForm.ButtonClick(Sender: TObject);
    begin
      createTask(TestTask).
      Run;
    end;

    procedure TMyForm.TestTask(const Task: IOmniTask);
    type
      TMyProc = reference to procedure;

    function CaptureValue(Value: Integer): TMyProc;
      begin
        Result := procedure begin Memo.Lines.add(Value.ToString); end;
      end;

    var
      i: Integer;
      Proc: TMyProc;
    begin
      Task.Invoke(procedure begin Memo.Lines.Add('Test 1 - Using Invoke (Outputs same value each time)'); end );
      for I := 0 to 2 do
        Task.Invoke(procedure begin Memo.Lines.Add(i.tostring); end );

      Task.Invoke(procedure begin Memo.Lines.Add('Test 2 - Using Invoke  with TMyProc and CaptureValue (Outputs same value each time)'); end );
      for I := 0 to 2 do
        begin
          Proc := CaptureValue(i);
          Task.Invoke(procedure
          begin
            Proc();
          end
          );
        end;
    end;

    end.

    OTLInvoke.dpr

    OTLInvokeMain.dfm

    OTLInvokeMain.pas

    • Thanks 1

  3. Thank you very much.  Your code indeed works but not in the context of an omnithread invoke

      for I := 0 to 9 do
        begin
          SetLength(Procs,Length(Procs)+1);
          Procs := CaptureValue(i);
          Procs();  //This line works
          Task.invoke(procedure begin Procs(); end ); //This line Access Violation
        end;

     

     


  4. Thank you for the reply but unfortunately this does not work either

     

    procedure TMyFormTestTask(const Task: IOmniTask);
    type
      TMyProc = reference to procedure;

     

    function CaptureValue(Value: Integer): TMyProc;
      begin
        Result := procedure begin mmoLogs.Lines.add(Value.ToString); end;
      end;

    var
      i: Integer;
      Proc: TMyProc;


    begin

      for I := 0 to 9 do
        begin
          Proc := CaptureValue(i);
          Task.Invoke(procedure
          begin
            Proc();
          end
        );

     

    //

    Gives a result of
    10
    10
    10
    10
    10
    10
    10
    10
    10
    10


  5. How can I update the UI from a task using invoke.  In my example below the memo is updated but with the wrong values

     

    procedure TMyForm.TestTask(const Task: IOmniTask);
    var
      i: Integer;
    begin
     for I := 0 to 4 do
       Task.Invoke(procedure
         begin
           mmoLogs.Lines.Add('['+i.ToString+']');
         end
       );

    end;

     

    result is 

    [4]

    [4]

    [4]

    [4]

    [4]

     

    I need it to be 

    [0]

    [1]

    [2]

    [3]

    [4]

     

    How can I achieve this?

     

    • Thanks 1
×