2

How can I completely terminate this background thread from the main thread, i.e. that not even the code in OnTerminated will be executed?

uses
  CodeSiteLogging,
  OtlParallel, OtlTaskControl, OtlTask;

procedure TForm2.btnParallelAsyncClick(Sender: TObject);
begin
  CodeSite.Send('btnParallelAsyncClick 1');

  Parallel.Async(
    procedure(const task: IOmniTask)
    var
      a: Integer;
    begin
      // executed in background thread:
      a := 1 + 1;
      Sleep(2000);
      CodeSite.Send('Executed in Async Thread', a);

      task.Invoke( // used to execute code in main thread
        procedure
        begin
          CodeSite.Send('task.Invoke executed in main thread', a);
        end);

      Sleep(2000);
      CodeSite.Send('Again executed in Async Thread', a);
    end,
    Parallel.TaskConfig.OnTerminated(
    procedure(const task: IOmniTaskControl)
    begin
      // executed in main thread:
      CodeSite.Send('After background thread termination: Executed in Main Thread');
    end
    )
    );

  CodeSite.Send('btnParallelAsyncClick 2');
end;
user1580348
  • 5,721
  • 4
  • 43
  • 105

1 Answers1

3

You can't do that (apart from killing the thread, but please don't do that).

Add a global flag shouldSkipTerminate, set it to false before creating the task, set it to true before you terminate the task and check if this flag is set in OnTerminated.

gabr
  • 26,580
  • 9
  • 75
  • 141
  • Thanks, Gabriel. I've tried this, but it doesn't seem to work: http://i.imgur.com/Xam1273.png – user1580348 Dec 30 '16 at 16:08
  • This one works: http://i.imgur.com/UnhfHDZ.png But this seems to be a primitive solution. Isn't it possible to actively terminate the `Async` thread with something like `task.Terminate` which doesn't work for me in the above example? – user1580348 Dec 30 '16 at 17:00
  • 3
    @user1580348 no. `Terminate` simply signals the task to stop running, but the task itself needs to cooperate by exiting itself when signaled. – Remy Lebeau Dec 30 '16 at 19:22
  • 1
    To help speed up terminating use TEvent.WaitFor instead of Sleep. Then when you want to terminate, signal the Event and check your TWaitResult: If (MyEvent.Waitfor(2000) <> System.Types.wrTimeout) or Terminated then Exit; – FredS Dec 30 '16 at 20:29
  • Thank you for your very useful comments, Gabriel! BTW, is it possible to set a priority with `SetPriority` to the `Parallel.Async` background task? – user1580348 Dec 30 '16 at 20:48
  • @user1580348 That's a separate question. [Ask a new question](http://stackoverflow.com/questions/ask) – Disillusioned Dec 31 '16 at 08:37