My program becomes unresponsive while performing a loop (Lazarus)

974 views Asked by At

I wrote a simple graphical program. It seemed to work, but when I clicked the Button (Button1), the program became unresponsive and began to respond only when the assigned procedure ended. I was using the simple Repeat...Until loop. Here's the procedure:

procedure TSlashForm.Button1Click(Sender: TObject);
begin
 Repeat
  //some code
 until //some condition;
end; 

If I click the form during the execution of the loop, the whole program becomes unresponsive and crashes. To fix this, I have tried to use

SlashForm.Update;

and

SlashForm.Refresh;

but none of these seemed to work. How can I avoid the unresponsive state?

2

There are 2 answers

2
Marco van de Voort On BEST ANSWER

Or call application.processmessages in the loop every 100-1000 iterations or so. (or roughly 5-10 times a second if you have slow iterations)

0
jwdietrich On

You could also use multithreading. In this variant, your program responds to clicking the button by creating a thread that performs your loop:

type
  TAThread = class(TThread)
  public
    procedure Execute; override;
    procedure SafeFree;
  end;

theThread: TAThread;

procedure TAThread.Execute;
var
  //some variables
begin
  repeat
  // some code
  until // some condition
end;

procedure TSimulationThread.SafeFree;  {avoids a dead-lock situation}
begin
  Terminate;
  WaitFor;
  if not FreeOnTerminate then
    Free;
end;

procedure TSlashForm.Button1Click(Sender: TObject);
begin
  if assigned(theThread) then
    theThread.Execute
  else
    theThread := TAThread.Create(false);
end;

See http://sourceforge.net/p/simthyr/code/HEAD/tree/trunk/simulator.pas for a working example.