Перейти к содержанию
Fire Monkey от А до Я
  • 0

Фоновое выполнение операции без "замораживания" отрисовки


97mik

Вопрос

Как сделать так, чтобы во время выполнения долговременных операций у меня не "замораживался" интерфейс приложения? 
 
Например, я выполняю по сети скачивания большого файла и на время скачивания отображаю индикатор загрузки. Но пока файл полностью не загрузиться индикатор не работает.

Изменено пользователем Brovin Yaroslav
Изменена формулировка вопроса для лучшего понимания.
Ссылка на комментарий

Рекомендуемые сообщения

  • 0
  • Администраторы

Вся отрисовка выполняется в главном потоке приложения. Поэтому, если вы пытаетесь выполнить скачивание файла в основном потоке, то вся отрисовка приостановится до момента окончания вашей операции. Поэтому правило хорошего тона - это вынесение долгих операций (загрузка, ответ авторизации и тд) в отдельный поток. 
 
Примерный код приведен ниже:
1. Создаем отдельный поток, в котором вы будите скачивать файл (я поставил для эмуляции скачивания просто паузу на 5 секунд):

type

  TMyTask = class (TThread)
  protected
    FOnTaskStarted: TThreadMethod;
    FOnTaskFinished: TThreadMethod;
    procedure DoStarted;
    procedure DoFinished;
    procedure Execute; override;
  public
    property OnTaskStarted: TThreadMethod read FOnTaskStarted write FOnTaskStarted;
    property OnTaskFinished: TThreadMethod read FOnTaskFinished write FOnTaskFinished;
  end;

Реализация:

{ TMyTask }

procedure TMyTask.DoFinished;
begin
  if Assigned(OnTaskFinished) then
    OnTaskFinished;
end;

procedure TMyTask.DoStarted;
begin
  if Assigned(OnTaskStarted) then
    OnTaskStarted;
end;

procedure TMyTask.Execute;
begin
  Synchronize(DoStarted);
  try
    Sleep(5000); // Эмуляция выполнения 5 Секундной задачи
  finally
    Synchronize(DoFinished);
  end;
end;

Само использование такого потока будет следующим (в моем примере после выполнения операции, появится сообщение):

  TForm3 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    FMyTask: TMyTask;
  public
    procedure DoTaskStarted; // Callback, вызываемый в начале старта операции
    procedure DoTaskFinished; // Callback, вызываемый в конце выполнения операции. Аналог OnTerminate
    procedure StartMyTask; // Запуск задачи
  end;
procedure TForm3.Button1Click(Sender: TObject);
begin
  StartMyTask;
end;

procedure TForm3.DoTaskStarted;
begin
end;

procedure TForm3.DoTaskFinished;
begin
  ShowMessage('Выполнение задачи окончено');
end;

procedure TForm3.StartMyTask;
begin
  if FMyTask <> nil then
  begin
    FMyTasl.OnTaskStarted := nil;
    FMyTasl.OnTaskFinished := nil;
    FMyTask.Free;    
  end;

  FMyTask := TMyTask.Create(True);
  FMyTask.OnTaskStarted := DoTaskStarted;
  FMyTask.OnTaskFinished := DoTaskFinished;
  FMyTask.Start;
end;

При таком подходе главный поток не будет блокироваться и будет корректно отрисовываться и работать.

Ссылка на комментарий
Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...