Как выйти из цикла for по нажатию на кнопку?

Как выйти из цикла при нажатии на другую кнопку (Остановить выполнение Button1Click) при нажатии на кнопку Button2Click:

Кнопка с циклом:

procedure TForm1.Button1Click(Sender: TObject);
var
  A: TStringDynArray;
  X: array of TStringDynArray;
  i, j: integer;
  NewFileName, s: String;
begin
  if not OpenDialog1.Execute then Exit;
  A := TFile.ReadAllLines(OpenDialog1.FileName);
  SetLength(X, Memo1.Lines.Count);
  for i := Low(A) to High(A) do
    for j := 0 to Memo1.Lines.Count - 1 do
      begin
        s := Trim(Memo1.Lines[j]);
        if Copy(A[i], 1, Length(s)) = s then
          begin
            SetLength(X[j], Length(X[j]) + 1);
            X[j, High(X[j])] := A[i];
          end;
      end;
  for i := 0 to Memo1.Lines.Count - 1 do
    begin
      NewFileName := Format('%s%s.txt', [ExtractFilePath(OpenDialog1.FileName), Memo1.Lines[i]]);
      if Length(X[i]) > 0 then TFile.WriteAllLines(NewFileName, X[i]);
    end;
end;

Кнопка остановить:

procedure TForm2.Button2Click(Sender: TObject);
begin
 // Break;
end;

Я так понимаю Break; не подходит к циклу for i ?


Ответы (1 шт):

Автор решения: MBo

Break прекрасно прерывает циклы, в том числе и For.

А не срабатывает прерывание потому, что пока не завершится обработчик первой кнопки, обработчик второй не будет вызван.

Как преодолеть - вынести долго исполняющийся код в отдельный поток. Это не так уж просто, если нужно обмениваться данными между основным потоком и дополнительным - а в приведённом примере всё зачем-то завязано на визуальные контролы (TMemo).

Во многих случаях можно обойтись периодической проверкой флага внутри цикла, а для обеспечения опроса второй кнопки вставить принудительную обработку сообщений (Application.ProcessMessages). Метод не рекомендуется для широкого применения - это костыль, когда нужно быстро обеспечить какую-никакую работоспособность.

  for i := Low(A) to High(A) do begin
    Application.ProcessMessages;
    if boolFlag then Break;
    ...
  end;

procedure TForm2.Button2Click(Sender: TObject);
begin
  boolFlag := True;
end;
→ Ссылка