Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка DELPHI.DOC
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.73 Mб
Скачать

Класс tthread

Для реализации потоков Delphi предоставляет класс TThread. Наиболее важными методами являются Execute и Synchronize. Первый метод осуществляет выполнение потока. Этот метод абстрактный. Поэтому необходимо создать класс, который является потомком TThread, и в этом классе переопределить метод Execute. Второй метод Synchronize, чтобы избежать одновременного использования компонентов приложения, сообщает основной подзадаче, что требуется обращение к ресурсам, которые, возможно, заняты. При этом передается адрес метода, который основная подзадача может вызвать, чтобы выполнить требуемую потоком работу. Процесс извещения является последовательным и основная подзадача должна полностью завершить выполняемую работу, прежде чем получить следующее извещение. Извещающее сообщение отсылается при помощи подпрограммы Windows SendMessage. Результатом является то, что подзадача будет заморожена вплоть до полной отработки задания внутри основной подзадачи.

В программе перед выполнением потока, являющегося классом, естественно, должен быть построен соответствующий объект. Для этого вызывается метод Create, имеющий один аргумент CreateSuspended типа Boolean. Если поток создан со значением аргумента CreateSuspended = false, то он немедленно (как только получит время процессора в соответствии с его собственным приоритетом и приоритетом процесса) начинает выполняться (запускается метод Execute), в противном случае Execute запускается вызовом метода Resume. Внутри метода Execute могут выполняться некоторые циклические действия, для завершения которых можно воспользоваться свойством Terminated. Устанавливая значение этого свойства равным true или внутри метода Execute или извне, поток получает команду о завершении его работы. С помощью метода Suspend можно приостановить работу потока и затем продолжить, вызывая метод Resume. Переустанавливая значение свойства Priority, можно управлять приоритетом потока.

Пример 27

Рассмотрим простой пример по использованию одного дополнительного потока. Пусть некоторый поток с помощью собственного метода, например, Paint применяется для закраски некоторой области прямоугольной формы. Основной поток приложения создается для рисования окружностей внутри той же области с помощью обработчика OnMouseDown.

Для построения приложения необходимо создать проект с двумя модулями. Один модуль – основная программа с объявленной переменной типа поток в секции Public внутри создавемого класса формы, другой модуль – модуль потока. Поместим на форму две кнопки TButton. Создадим для них два обработчика OnClick. Для формы, как уже отмечено, создается обработчик OnMouseDown. Далее создадим модуль для реализации вспомогательного потока (основной поток автоматически создается для процесса (приложения)).

Необходимо открыть меню File - New и выбрать пункт Other. Откроется диалоговое окно, в котором нужно выбрать (дважды щелкнуть мышкой) значок Thread Object. Когда появится диалоговое окно для именования объекта поток, необходимо ввести имя класса TThread (Class Name = TPaintThread) и нажать на кнопку OK. Ниже приводится весь программный код данного примера, который демонстрирует использование метода Synchronize.

unit MyThread1; {Модуль для определения потока}

interface

uses Classes;

type

TPaintThread = class(TThread)

private

x,y:integer;

protected

procedure Execute; override;

procedure Paint;

end;

implementation

uses Unit27_1, Graphics;

procedure TPaintThread.Execute;

begin

randomize;

Repeat

x:=random(250);

y:=random(Form1.ClientHeight);

Synchronize(Paint);

until Terminated;

end;

procedure TPaintThread.Paint;

begin

Form1.Canvas.Pixels[x,y]:=clPurple;

end;

end.

unit Unit27_1; {Основной модуль}

interface

uses

Windows, Messages, SysUtils, Variants, Classes,

Graphics, Controls, Forms,

Dialogs, StdCtrls, ExtCtrls, Buttons, MyThread1;

type

TForm1 = class(TForm)

Button1: TButton;

Button2: TButton;

BitBtn1: TBitBtn;

procedure Button1Click(Sender: TObject);

procedure Button2Click(Sender: TObject);

procedure FormMouseDown(Sender: TObject; Button:

TMouseButton; Shift: TShiftState; X, Y: Integer);

public

MyPaintThread:TPaintThread;

end;

var Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

begin

Button1.Enabled:=false;

Button2.Enabled:=true;

MyPaintThread:=TPaintThread.Create(false);

end;

procedure TForm1.Button2Click(Sender: TObject);

begin

MyPaintThread.Free;

Button1.Enabled := True;

Button2.Enabled := False;

end;

procedure TForm1.FormMouseDown(Sender: TObject;

Button: TMouseButton; Shift: TShiftState;

X, Y: Integer);

begin

Canvas.Pen.Color := Color;

Canvas.Brush.Color := Color;

Canvas.Ellipse (x - 30, y - 30, x + 30, y + 30);

end;

end.

Следует обратить внимание на строку MyPaintThread:TPaintThread; и использование модуля Graphics. Среда Delphi может не добавить этот модуль в список Uses. На рис. 63 приводится вариант решения данного примера.

Рис. 63. Вариант решения примера 27.