Итак вводную часть данной темы я делал в этом посте, поэтому пора приступать к практике, не правда ли?. Давайте немного вспомним, что потоки помогают выполнять одновременно несколько функций программы не мешая друг другу, а также не мешая главному потоку программы. Это очень популярно в настоящее время и сейчас большинство, особенно, крупных программных разработок, работают с использованием потоков. Давайте и мы будем использовать потоки в своем приложении, только не забывайте, что потоками злоупотреблять нельзя, многие используют потоки в своих программах, приложениях совсем там, где они ненужны, или там, где можно обойтись обычным Application.ProcessMessages;
На форме у меня следующие компоненты
- TButton
- TEdit
В данном примере мы будем в цикле увеличивать переменную и отображать ее в TEdit, тем самым будем пробывать передвигать окно, набирать в другом TEdit какие-либо данные, и цикл будет проходить до 65000, чтобы было заметно и немного времени прошло. Давайте создадим новый поток, не забываем, что за это отвечает класс TThread. Вы можете создать с помощью мастера, для этого выполняем File-New-Other во вкладке New выбираем Thread Object и нажимаем OK. Далее в появившемся окне пишем имя нашего потока и кнопка ОК. Но если Вы создаете мастером, то не забудьте в модуль потока подключить модуль вашего проекта, а в модуль вашего проекта подключить модуль потока (подключать в Uses). Я создавал все в одном модуле и класс потока у меня выглядит так
type
MyThread=class(TThread)
private
results:integer;
protected
procedure ShowResult;
procedure Execute; override;
end;
переменная results - будет увеличиваться в цикле на 1 и отображаться в TEdit. Процедура ShowResult - будет выводить наш результат в TEdit, а Execute — основная процедура потока, в которой и выполняется сам поток.
Далее я поставил курсор на процедуру Execute и нажал клавиши Shift+Ctrl+C. Далее у меня сформировались процедуры, и в процедурe Execute я написал следующий код
procedure MyThread.Execute;
var
i:integer;
begin
inherited;
results:=0;
for i:=1 to 65000 do
begin
results:=results+1;
Synchronize(ShowResult);
end;
end;
То есть в цикле как я и говорил увеличиваем нашу переменную на 1. А с помощью процедуры Synchronize - сихронизируем наш результат. Процедура ShowResult у меня выглядит следующим образом
procedure MyThread.ShowResult;
begin
Form1.Edit1.Text:=IntToStr(results);
end;
То есть просто в TEdit мы выводим наш результат. Далее, чтобы наш поток выполнялся надо создать объект нашего класса, для этого на OnClick-событие компонента TButton я написал следующий код
procedure TForm1.Button1Click(Sender: TObject);
var
ThreadBegin:MyThread;
begin
ThreadBegin:=MyThread.Create(False);
ThreadBegin.Resume;
ThreadBegin.Priority:=tpNormal;
end;
Здесь должно быть все понятно, создаю поток, вызываю сразу Execute - это видно, что при создании я указываю False. Далее возобновляю на всякий случай поток и ставлю приоритет ему нормальный. Все у нас отображаются данные в TEdit и мы можем например в другом TEdit набирать любой текст и данные все равно у нас будут отображаться. Вот так все просто, далее рассмотрим что-нибудь серьезное