• Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

Delphi Многопоточность. Класс Tthread.

  • Автор темы Автор темы Lomanu4
  • Дата начала Дата начала

Lomanu4

Команда форума
Администратор
Регистрация
1 Мар 2015
Сообщения
1,467
Баллы
155
Класс TThread.
Для начала немного теории, которая понадобится нам для создания первого примера приложения с потоком.
Самое первое и самое главное: TThread - АБСТРАКТНЫЙ класс!!! Т.е. НИКОГДА не используйте его напрямую, а то потом долго не разберетесь, откуда появляется ошибка! Для использования класса TThread необходимо создать класс-потомок:
Код:
type
TMyThread = Class (TThread);
…
end;
Вот некоторые методы класса TThread, которые нам понадобятся для начала:
Код:
constructor Create(CreateSuspended: Boolean);
procedure Resume;
procedure Suspend;
function Terminate: Integer ;
procedure Execute; virtual; abstract;
procedure Synchronize (Method: TThreadMethod);

Параметр конструктора Create означает, как будет запущен поток после создания: немедленно (False) или попозже (True). Если Вы создали поток с параметром True, то для его запуска необходимо будет вызвать метод Resume.
Suspend - приостанавливает выполнение потока;
Resume - продолжает выполнение потока;
Terminate - пытается завершить поток путем установки свойства Terminated в True. Для прекращения выполнения потока во время работы, необходимо периодически проверять свойство Terminated в пределах метода Execute (см. ниже) и во всех мето-дах, которые Executeвызывает, и выходить, если Terminated=True.
Execute - содержит основной код потока, т.е. те действия, которые Вы решили по-местить в поток. Если Вы обратили внимание, этот метод абстрактный, т.е. его надо переопределять в пределах Вашего класса-потомка TThread.
Synchronize - используется для предотвращения одновременного доступа разных потоков к одному элементу VCL. Дело в том, что код VCL выполняется в главном потоке программы, так что поток должен синхронизироваться, если он использует код VCL. Параметр метода - это метод без параметров, который обычно принадле-жит Вашему потоковому классу.
И еще одно: не желательно создавать элементы VCL в потоке, т.к. сообщения системы не будут посылаться манипуляторам окон, созданных в потоке. Правда есть некоторые элементы VCL, которые являются потокозащищенными. Это TCanvas, который имеет методыLock и UnLock, которые запрещают и разрешают (соответст-венно) доступ к канве для других потоков. Кроме того, класс TThreadListпозволяет нескольким потокам работать с TList.

Ну вот, немного теории уже есть, пора и к практике переходить :)
Давайте для примера создадим простую программу, которая будет что-то, например - крестики, выводить на канву формы в единственном потоке.
Для этого нам понадобится создать новый проект, на форму которого нужно будет поместить всего две кнопки - Botton1 и Button2, а в секцию private описания формы добавим

PT : TMyThread;

Далее создадим свой собственный потоковый класс (перед описанием класса фор-мы!):
Код:
type
TmyThread = class (TThread)
private
X, Y, Color : Integer;
protected
procedure Execute; override;
procedure Paint;
end;
Далее, естественно, опишем методы Execute и Paint:
Код:
procedure TMyThread.Execute;
begin
Randomize;
X:=0;Y:=0;
repeat
X:=Random(Form1.Width);
Y:=Random(Form1.Height);
Color:=Random($FFFFFFFF);
{в методе Paint происходит обращение к элементу VCL - Canvas, по-этому необходима синхронизация}
Synchronize (Paint);
until Terminated;
end;
Код:
procedure TMyThread.Paint;
begin
with Form1.Canvas do begin
{рисуем крестики :-)}
Pixels[X,Y-1]:=Color;
Pixels[X+1,Y]:=Color;
Pixels[X-1,Y]:=Color;
Pixels[X,Y+1]:=Color;
Pixels[X,Y]:=Color;
end;
end;
И не забудем создать обработчики для кнопок:
Код:
procedure TForm1.Button1Click(Sender: TObject);
begin
Button1.Enabled:=False;
Button2.Enabled:=True;
PT:=TMyThread.Create(False); // запустить поток сразу
end;
Код:
procedure TForm1.Button2Click(Sender: TObject);
begin
Button1.Enabled:=True;
Button2.Enabled:=False;
PT.Free; // уничтожить поток
end;

Вот и все. Запускаем, должно получиться drink
 
Последнее редактирование:
Пиксели не окрашиваются в цвет. Код идентичен данному. В чем может быть проблема?
 
Пиксели не окрашиваются в цвет. Код идентичен данному. В чем может быть проблема?
Проверил всё работает:
Код:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;


type
TmyThread = class (TThread)
private
X, Y, Color : Integer;
protected
procedure Execute; override;
procedure Paint;
end;

var
  Form1: TForm1;
  PT : TMyThread;

implementation

{$R *.dfm}

{ TmyThread }

procedure TMyThread.Execute;
begin
Randomize;
X:=0;Y:=0;
repeat
X:=Random(Form1.Width);
Y:=Random(Form1.Height);
Color:=Random($FFFFFFFF);
{в методе Paint происходит обращение к элементу VCL - Canvas, по-этому необходима синхронизация}
Synchronize (Paint);
until Terminated;
end;

procedure TMyThread.Paint;
begin
with Form1.Canvas do begin
{рисуем крестики :-)}
Pixels[X,Y-1]:=Color;
Pixels[X+1,Y]:=Color;
Pixels[X-1,Y]:=Color;
Pixels[X,Y+1]:=Color;
Pixels[X,Y]:=Color;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Button1.Enabled:=False;
Button2.Enabled:=True;
PT:=TMyThread.Create(False); // запустить поток сразу
end;


procedure TForm1.Button2Click(Sender: TObject);
begin
Button1.Enabled:=True;
Button2.Enabled:=False;
PT.Free; // уничтожить поток
end;

end.
 
Вверх Снизу