title: Delphi OmniThreadLibrary and Async
body: <p>Hopefully a simple one.  I am using an OTL Parallel.For loop to process lots of data.  The amount of data can change and if there is a lot (that takes over 2 seconds) Windows flickers the application form and gives a temporary "not responding" status in the title bar.</p>
  
  <p>To get around this I thought I could put the procedure with the Parallel.For loop inside an OTL Async call, like</p>
  
  <pre><code>done:=false;
  Async(ProcedureThatDoesParallelFor).Await(
  procedure begin
  done:=true;
  end);
  repeat application.processmessages until done=true;
  </code></pre>
  
  <p>This works (or seems to work) but can lead to the program just aborting/exiting without any error messages.  It only seems to cause the silent abort problem when the Parallel.For loop is very quick to run.</p>
  
  <p>If I remark the above code and take the call to ProcedureThatDoesParallelFor outside of it the app runs fine without unexpected quitting, so I am assuming it must be the Async call causing the problem.  Or a combination of Parallel.For within Async?</p>
  
  <p>Is using Async the best way to run another procedure and wait for it to finish?  Is there a better OTL way of doing this?</p>
  
  <p>Thanks for any ideas or solutions.</p>
  
  <p>Here is the simplest example to show the crashing error.  Single form with a memo and button.  Click the button and the program will hang around iteration 300.</p>
  
  <pre><code>unit Unit1;
  
  interface
  
  uses
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,OtlParallel,OtlTaskControl;
  
  type
    TForm1 = class(TForm)
      Button1: TButton;
      Memo1: TMemo;
      procedure Button1Click(Sender: TObject);
    private
      { Private declarations }
    public
      { Public declarations }
    end;
  
  var
    Form1: TForm1;
  
  implementation
  
  {$R *.dfm}
  
  procedure AsyncParallelFor;
  var iterations:integer;
      blah:integer;
  begin
       iterations:=10;
       //for iter:=0 to limit-1 do
       Parallel.For(0,iterations-1).Execute(procedure(iter:integer)
       var x,y:integer;
       begin
            for y:=0 to 50 do
            begin
                 for x:=0 to 50 do
                 begin
                      blah:=x+y;
                 end;
            end;
       end);
  end;
  
  procedure AsyncProcedure;
  var done:boolean;
  begin
       done:=false;
       Parallel.Async(
            procedure
            begin
                 //executed in background thread
                 AsyncParallelFor;
            end,
            Parallel.TaskConfig.OnTerminated(
            procedure (const task: IOmniTaskControl)
            begin
                 //executed in main thread after the async has finished
                 done:=true;
            end
            )
       );
       //this point is reached immediately after the call to Async
       //the repeat loop waits until the Async is finished being signalled via done variable
       repeat
             application.processmessages;
       until done=true;
  end;
  
  
  procedure TForm1.Button1Click(Sender: TObject);
  var iters:integer;
  begin
       iters:=0;
       repeat
             memo1.lines.add('Iteration '+inttostr(iters)+'...');
             memo1.lines.add('Before Async');
             application.processmessages;
             AsyncProcedure;
             memo1.lines.add('After Async');
             application.processmessages;
             inc(iters);
       until 1&gt;2;
  
  
  end;
  
  end.
  </code></pre>
  
  <p>AsyncParallelFor shows the basic nested loops.  Just a simple addition in there to demo the issue.</p>
  
  <p>AsyncProcedure does the OTL Async call and waits for the return.</p>
  
  <p>I have a lot of non parallel code before and after the call to AsyncProcedure that need to wait for the parallel.for loop to finish.</p>
  
  <p>If I change the button click to call AsynParallelFor directly without the Async then there is no hang.</p>