Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Работа в отдельном потоке, которая не мешает основной программе

Delphi , Компоненты и Классы , Потоки

Работа в отдельном потоке, которая не мешает основной программе

Автор: Xavier Pacheco

unit ThrdU;

interface

uses
  Classes;

type
  TTestThread = class(TThread)
  private
    Answer: integer;
  protected
    procedure GiveAnswer;
    procedure Execute; override;
  end;

implementation

uses SysUtils, Main;

{ TTestThread }

procedure TTestThread.GiveAnswer;
begin
  MainForm.Edit1.Text := InttoStr(Answer);
end;

procedure TTestThread.Execute;
var
  I: Integer;
begin
  FreeOnTerminate := True;
  for I := 1 to 2000000 do
  begin
    if Terminated then
      Break;
    Inc(Answer, Round(Abs(Sin(Sqrt(I)))));
    Synchronize(GiveAnswer);
  end;
end;

end.
unit Main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ThrdU;

type
  TMainForm = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Memo1: TMemo;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MainForm: TMainForm;

implementation

{$R *.DFM}

procedure TMainForm.Button1Click(Sender: TObject);
begin
  TTestThread.Create(False);
end;

end.

Перевод контента на русский язык:

Код, предоставленный ниже, демонстрирует, как запустить отдельный поток в Delphi, который может быть полезен для выполнения задач без блокировки основного программы.

Вот разбивка на части:

  1. Класс TTestThread наследуется от TThread. У него есть два приватных переменные: Answer, которая хранит целочисленное значение, и другие свойства или методы.
  2. В процедуре GiveAnswer обновляется текстовое поле (Edit1) в основной форме с текущим значением Answer.
  3. Процедура Execute - это место, где поток выполняет свою работу. Она запускает цикл, который повторяется 2000000 раз, инкрементирует Answer с помощью вычисленного значения (абсолютная величина синуса квадратного корня номера итерации) и затем синхронизируется с основной формой, вызвав GiveAnswer.
  4. Свойство FreeOnTerminate установлено в True, что означает, что когда поток завершается (т.е., выполняет свою работу или остановлен), он автоматически освободит себя.

Единица Main содержит форму (TMainForm) с несколькими контролами, включая текстовое поле (Edit1), кнопку (Button1) и мем-фильд (Memo1). Метод обработки события Button1Click создает экземпляр класса TTestThread и запускает его выполнение.

Основной проблемой этого кода является то, что он не очень эффективен. Он не выполняет ничего полезного, просто инкрементирует переменную в цикле. В реальном приложении вы, вероятно, хотели бы выполнить некоторые конкретные задачи, такие как чтение или запись данных из файла или базы данных, отправку запросов по сети и т.д.

Еще одна проблема - это то, что поток выполняется бесконечно, пока не будет остановлен вручную. Если основная программа завершается до тех пор, как поток не выполнит свою работу, это может привести к утечкам памяти и другим проблемам. Более robust решение было бы дать пользователю возможность остановить поток в какой-то момент.

Вот возможное альтернативное реализацию:

type
  TTestThread = class(TThread)
  private
    FStop: Boolean;
    procedure GiveAnswer;
    procedure Execute; override;
  protected
    function DoWork: Boolean; override;
  public
    constructor Create(AStop: Boolean);
  end;

var
  StopThread: TThread;

constructor TTestThread.Create(AStop: Boolean);
begin
  inherited Create(False);
  FStop := AStop;
end;

procedure TTestThread.GiveAnswer;
begin
  MainForm.Edit1.Text := IntToStr(Answer);
end;

function TTestThread.DoWork: Boolean;
begin
  for I := 1 to 2000000 do
  begin
    if Terminated then
      Break;
    Inc(Answer, Round(Abs(Sin(Sqrt(I)))));
    Synchronize(GiveAnswer);
  end;
  Result := not Terminated;
end;

procedure TTestThread.Execute;
begin
  while not FStop do
    if DoWork then
      Exit;
  FreeOnTerminate := True;
end;

В этом варианте класс TTestThread имеет новый конструктор, который позволяет указать, должен ли поток остановиться или продолжить выполнение. Он также имеет метод DoWork, который выполняет фактическую работу потока и возвращает булевое значение, указывающее, был ли поток остановлен пользователем.

Процедура Execute теперь использует этот метод DoWork для запуска цикла до тех пор, пока он не будет остановлен, а затем освобождает себя, если он был остановлен вручную.

В статье описана реализация работы в отдельном потоке на языке Delphi, которая не влияет на основную программу и позволяет выполнить задачи в фоновом режиме.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Потоки ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 13:19:55/0.0058209896087646/1