Пример создания многопоточного приложения в Delphi
Теперь настало время для собственного многопоточного приложения.
Мы создадим простое приложение, которое состоит из трех потоков. Для начала запустим Delphi и выберем в главном меню Delphi пункт File/New Application (Файл/Новое приложение). После чего, разместим на главной форме приложения (Forml) поле для редактирования (Edit), индикатор хода выполнения работы (Progress Bar) и системный таймер (Timer). В результате должна получиться форма, аналогичная представленной на рис. 1.26.
Рис. 1.26. Форма примера многопоточного приложения
Теперь добавим новый объект потока через пункт главного меню Delphi File/New/Thread Object (Файл/Новый/Объект потока). Введем имя для нового потомка класса TThread, например TMyThreadl. Delphi автоматически добавит модуль Unit2 в наше приложение. В описании объекта TMyThreadl добавим раздел public, в котором опишем глобальную переменную count. В результате должно получиться следующее:
type
TMyThreadl = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
public
count:integer;
end;
Далее запишем в метод Execute объекта TMyThreadl код, который должен выполняться в потоке. Пусть это будет код, который генерирует случайные числа и присваивает их глобальной переменной count. Для того чтобы генерация случайных чисел была бесконечной, зациклим ее с помощью так называемого "бесконечного цикла":
procedure TMyThreadl.Execute;
begin
while true do
begin
count:=random(maxint);
end;
end;
Теперь создадим второй объект потока, который должен заполнять индикатор хода работы (Progress Bar).
По аналогии с первым объектом потока, при помощи главного меню Delphi создадим объект потока с именем TMyThread2. Во вновь добавленном модуле units определим глобальную переменную prcount:
type
TMyThread2 = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
public
prcount:integer;
end;
После чего в процедуре Execute объекта TMyThread2 запишем следующий код, также зациклив его:
procedure TMyThread2.Execute;
begin
while true do
begin
prcount:=prcount+l;
if prcount>100 then prcount:=0;
end;
end;
Теперь сохраним наш проект и модули под теми именами, которые нам предложит Delphi (Projectl, Unitl, Unit2, Unit3).
Добавим в модуле uniti в описание класса формы в разделе private объекты потоков Threadl - потомок класса TMyThreadl и Thread2 - потомок класса TMyThread2:
type
TForml = class(TForm)
ProgressBarl: TProgressBar;
Editl: TEdit;
Timerl: TTimer;
procedure FormCreate(Sender: TObject);
private
Threadl:TMyThreadl;
Thread2:TMyThread2;
public
{ Public declarations }
end;
Далее, дважды щелкнем на любом свободном пространстве формы Form1. При этом откроется "заготовка" для метода создания формы FormCreate формы Formi. В обработчике FormCreate напишем следующий код:
procedure TForml.FormCreate(Sender: TObject);
begin
Threadl:=TMyThreadl.Create(False);
Threadl.priority:=tpLowest;
Thread2:=TMyThread2.Create(False);
Thread2.priority:=tpNormal;
end;
Здесь мы создаем объект потока с использованием конструктора Create и устанавливаем приоритеты потоков (tpLowest и tpNormal).
Примечание
Единственный параметр, который передается в методе Create класса TThread- CreateSuspended. Данный параметр может принимать логическое значение истины или лжи (true, false). Этот параметр показывает, создавать поток в приостановленном состоянии (true) или запускать его сразу же (false). То есть метод Execute будет вызван автоматически сразу, если параметр CreateSuspended равен false (как в нашем случае). Если же мы хотим запускать поток на исполнения в другое время, необходимо установить параметр CreateSuspended в true и воспользоваться методом Resume для вызова метода Execute на исполнение.
Запишем в-блоке uses модуля unit1 используемые модули unit2 и unit3:
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Unit2, Unit3, StdCtrls, ComCtrls;
Нам осталось отразить результаты вычислений, производимых потоками на форме. Для этого создадим обработчик события OnTimer, дважды щелкнув на объекте Timer1. Запишем в обработчик события OnTimer следующий код:
procedure TForml.TimerlTimer(Sender: TObject);
begin
editl.text:=inttostr(threadl.count);
progressbarl.position:=thread2.prcount;
end;
Все! Наше первое приложение, которое использует потоки, готово! Теперь, если запустить приложение с помощью главного меню Delphi: Run/Run (Запуск/Запуск), то мы можем видеть, как два созданных нами потока работают, причем с разной скоростью (в зависимости от приоритета).